ES——Promise
先看一段代码,这是我们这边普遍的异步通信模式,采用callback的写法,将回调函数层层传入
const func1 = (callback)=> {
  $.ajax({
    ...,
    success: (res)=> {
      console.log('武林要以和为贵');
      func2(callback, res)
    }
  })
}
const func2 = (callback, data)=> {
    $.ajax({
        ...,
        success: (res)=> {
						console.log('要讲武德');
            callback()
        }
    })
}
func1(()=> {
    console.log('不要搞窝里斗');
}) 
//输出结果为:武林要以和为贵,要讲武德,不要搞窝里斗
一、Promise 概览
Promise
- 语法上讲是一个对象(类),可以用来获取异步操作的内容消息
- 从本意上讲,被译为期约,是对当前函数调用状态的一种保证
- 从用途上讲,是异步编程的一种解决方案,比回调函数(callback)和事件(event)更合理
Promise 主要解决两个问题
- 
解决异步问题,实现多并发请求 
- 
解决回调地狱 //有多个异步任务,要求需要同时拿到所有异步任务的结果,下边就是用回调函数的方法造成的回调地狱 $.get("url", (res1) => { conosle.log(res1) $.get("url+res1", (res2) => { conosle.log(res2) $.get("url+res2", (res3) => { conosle.log(res3) $.get("url+res3", (res4) => { conosle.log(res4) }) }) }) })
Promise 的特点
- 
Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态 
- 
一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的 
二、Promise 用法
ajax 的 Promise 改造
/**
 * 
 * @param {*} data - {type, url, data}
 * @returns 
 */
const ajaxToPromise = (data)=> {
    return new Promise((resolve, reject)=> {
        const xhr = new XMLHttpRequest()
        if (data.type === "get") {
            if(data.data) {
                data.url += "?" + Param(data.data)
            }
            //调用open()方法并采用异步方式
            xhr.open("get", data.url, true);
            //使用send()方法将请求发送出去
            xhr.send();
        } else if (data.type === "post") {
            xhr.open("post", data.url, true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.send(Param(data.data))
        }
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    resolve(JSON.parse(xhr.responseText));
                } else {
                    reject("Err:" + xhr)
                }
            }
        }
    })
}
Promise.prototype.then() & Promise.prototype.catch()
ajaxToPromise({
    url: 'http://localhost:3007/playerInfo',
    type: 'get',
    data: ''
}).then(res=> {
    console.log(res);
}).catch(err=> {
    console.log(err);
})
- then( resolvedCallback , rejectCallback(可选) )
- 第一个参数接受resolved状态的回调函数,第二个为可选参数,接受rejected状态的回调函数
- then() 方法返回新的 Promise 对象,所以可以链式调用
 
- catch( rejectCallback )
- 
是 then( null , rejectCallback ) 的别名,但是不建议使用 then 的错误回调方式,因为 Promise 的状态是冒泡的,错误状态将会层层传递,即最后一个 catch 会接受以前所有的错误信息,更加接近于同步写法(try/catch) request().then(resolvedCallback).then(resolvedCallback).catch(rejectCallback) // Better Than request().then(resolvedCallback).then(resolvedCallback, rejectCallback)
- 
unhandledRejection 
 
- 
Promise.resolve() & Promise.reject()
都是将现有对象转为 Promise 对象,前者是 fulfilled 状态,后者是 rejected 状态
new Promise(resolve => resolve())
new Promise((resolve,reject)=> reject())
Promise.all() & Promise.race()
两者都接收一个具有 Iterator 接口且返回的每个成员都是 Promise 实例的参数,如 Promise 数组
- all() 即且函数,当所有 Promise 实例都返回 fulfilled 的状态时才能触发 all 函数的 fulfilled
- race() 即或函数,当任一Promise实例为 fulfilled,race 函数就会返回 fulfilled
应用:C 函数必须在互不关联的 A 和 B 执行完后执行
Promise.all([A, B])
.then(res=> { C() })
.catch(err=> console.log(err))
Promise.done() & Promise.finally()
- 
Promise.done(resolvedCallback, rejectedCallback) 总是存在于链式调用的最后,接收前面所有的报错并向全局抛出 Promise.prototype.done = function(onFulfilled, onRejected) { this.then(onFulfilled, onRejected) .catch(function(reason){ // 抛出全局错误 setTimeout(()=> {throw reason}, 0) }) }
- 
Promise.finally(callback) 无论前面的 Promise 返回的状态如何,都会执行该 callback Promise.prototype.finally = function(callback) { let P = this.constructor return this.then( value => p.resolve(callback()).then(()=> value), reason => P.resolve(callback()).then(()=> {throw reason}) ) }
 
	
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号