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号