基础篇主要是介绍了Promise的基本使用方法和特点,进阶篇讲讲Promise的复杂使用方式等。
Promise连锁和Promise合成
Promise连锁
由于每个Promise实例都会返回一个新的Promise对象,并且返回的Promise对象有自己的实例方法,通过调用返回的Promise实例的方法来生成新的Promise对象,再调用其方法。这种连缀方法调用就是Promise连锁。
function delayedExecute(str, callback = null) {
setTimeout(() => {
console.log(str)
callback && callback()
}, 1000)
}
delayedExecute('p1 callback', () => {
delayedExecute('p2 callback', () => {
delayedExecute('p3 callback', () => {
delayedExecute('p4 callback', () => {
})
})
})
})
// p1 callback (1秒后)
// p2 callback (2秒后)
// p3 callback (3秒后)
// p4 callback (4秒后)
复制代码
用Promise连锁来解决这个依赖回调的回调地狱问题:
function delayedExecute(str) {
return new Promise((resolve, reject) => {
console.log(str)
setTimeout(resolve, 1000)
})
}
delayedExecute('p1 excutor')
.then(() => delayedExecute('p2 excutor'))
.then(() => delayedExecute('p3 excutor'))
.then(() => delayedExecute('p4 excutor'))
// p1 excutor (1秒后)
// p2 excutor (2秒后)
// p3 excutor (3秒后)
// p4 excutor (4秒后)
复制代码
Promise图
因为一个Promise可以有多个处理程序,所以Promise连锁可以构建有向非循环图结构。每个Promise实例都是途中的一个顶点,而使用实例方法添加的处理程序则是有向顶点。因为图中的每一个节点都会等待前一个节点落定,所以图的方向就是Promise的解决或拒绝的顺序。
下面是用Promise来表示一个Promise有向图,也就是二叉树:
// A
// / \
// B C
// / \ / \
// D E F G
let A = new Promise(resolve => {
console.log('A')
resolve()
})
let B = A.then(() => console.log('B'))
let C = A.then(() => console.log('C'))
B.then(() => console.log('D'))
B.then(() => console.log('E'))
C.then(() => console.log('F'))
C.then(() => console.log('G'))
// A
// B
// C
// D
// E
// F
// G
复制代码
Promise连锁能表示二叉树是因为Promise的处理程序是先添加到消息队列,然后才逐个执行,因此构成了二叉树的层序遍历。
Promise.all()
这个静态方法接收一个可迭代对象,并返回一个新的Promise对象,这个对象也称为合成Promise对象。
语法:Promise.all([arg1, arg2, …])
特点:
-
可迭代对象中的元素会通过Promise.resolve()转换为Promise对象。
-
空的可迭代对象等价于Promise.resolve()。
-
不传入可迭代对象则会抛出类型错误。
-
合成对象为resolved状态:
- 只有当可迭代对象的所有元素的Promise对象都resolved了,合成对象才会resolved。
- 合成对象的resolvedResult值是所有Promise对象的resolvedResult组成的数组,并且该数组的顺序就是可迭代对象中元素的顺序。
-
合成对象为pending状态:
可迭代对象的元素中只要有一个Promise对象是pending状态,则合成对象的状态就是pending。
-
合成对象为rejected状态:
- 可迭代对象的元素中,只要又一个Promise对象是rejected状态,则合成对象的状态就是rejected。
- 合成对象的rejectedResult值是第一个rejected对象的rejectedResult。
- 后面rejected的Promise对象不会影响已经rejected的合成对象的rejectedResult值。
- 合成Promise对象会静默处理所有包含rejected的Promise对象操作,即不再抛出异常。
let p1 = Promise.all([ Promise.reject(1), new Promise((null, reject) => { setTimeout(reject, 0, 2) }) ]) let p2 = p1.catch(err => { console.log(err) // 1 }) console.log(p1) // Promise <rejected>: 1 console.log(p2) // Promise <fulfilled>: undefined 复制代码
Promise.race()
串行Promise合成
Promise扩展
Promise取消
Promise进度通知
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END