ES6-Promise进阶篇

基础篇主要是介绍了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
喜欢就支持一下吧
点赞0 分享