zoukankan      html  css  js  c++  java
  • 将已经存在的异步请求callback转换为同步promise

    由于js是单线程执行,为防止阻塞,会有很多异步回调函数callback,嵌套层次多了,可读性就差了很多。随着社区的发展,出现了promise。我们来将一些常见的回调函数做修改,变成promise的链式调用,简洁,清晰明了。

    先理解一点点概念。

    每个promise都有三个状态。pending、Fulfilled、Rejected。最初为pending,状态一但改变为Fulfilled、Rejected中的一种,即成永远,不再改变。

    pending: 等待状态。

    Fulfilled: 表示成功完成。

    Rejected: 表示被拒绝,失败。

    原生的ajax请求

    
    /**
     * 原生请求
     */
    function nativeRequest(url) {
      var xhr = new XMLHttpRequest()
      // 这里我建议的书写顺序是: onreadystatechange -> open -> send
      // 这样,onreadystatechange 可以获取 readyState 的状态 1 2 3 4
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) { // 请求已完成,且响应已就绪
          if (xhr.status === 200) {
            // TODO: 处理返回正常的数据 xhr.responseText
          } else {
            // TODO: 处理返回非正常的数据
          }
        }
      }
      xhr.open('GET', url, true)
      xhr.send(null)
    }
    

    promise 风格的请求

    /**
     * promisify request
     * 返回promise对象 
     */
    function promiseRequest(url) {
      return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4) {
            if (xhr.status === 200) {
              resolve(xhr.responseText)
            } else {
              reject(xhr.responseText)
            }
          }
        }
        xhr.open('GET', xhr, true)
        xhr.send(null)
      }).catch(err => {
        console.log(err)
      })
    }
    
    

    jquery中的ajax请求

    这里只使用ajax请求中的get请求,使用常见的几个参数。

    
    /**
     * ajax get请求
     */
    function ajaxResponse(url) {
      $.ajax({
        url: url,
        type: 'GET',
        success: res => {
          console.log(res)
        },
        error: err => {
          console.log(err)
        }
      })
    }
    

    转换为promise风格

    /**
     * promise风格的ajax get请求
     * 返回promise对象 
     * 这里同时用到了es6中的解构赋值默认值和函数参数默认值
     */
    function promiseAjaxResponse(url, {
        type = 'GET',
        } = {}) {
      return new Promise((resolve, reject) => {
        $.ajax({
          url,
          type,
          success: res => {
            resolve(res)
          },
          error: err => {
            reject(err)
          }
        })
      })
    }
    
    

    node风格的callback请求

    
    nodeGet(param, function (err, data) { })
    
    

    TO:

    
    function nodeGetAysnc(param) {
    
      return new Promise((resolve, reject) => {
    
        nodeGet(param, function (err, data) {
    
          if (err !== null) return reject(err)
    
          resolve(data)
    
        })
    
      })
    
    }
    
    

    DOM load事件 或者其他一次性事件

    
    function load() {
    
      console.log('onload - end')
    
    }
    
    window.onload = load
    
    

    TO promise

    
    function promiseLoad() {
    
      return new Promise(function (resolve, reject) {
    
        window.onload = resolve
    
      })
    
    }
    
    promiseLoad().then(load)
    
    

    参考

    1.How do I convert an existing callback API to promises?
    2.How do I promisify native XHR?

  • 相关阅读:
    面向过程编程
    生成器
    迭代器
    装饰器
    函数对象与闭包
    名称空间和作用域
    Django中的as_view方法源码分析
    DRF3序列化反序列化
    DRF4级联与外键字段
    django--BBS项目,后端业务逻辑整理
  • 原文地址:https://www.cnblogs.com/weiqinl/p/9651515.html
Copyright © 2011-2022 走看看