乐趣区

关于promise:研究当resolve函数参数里是另外一个Promise实例

起因

明天遇到一个题目,钻研了一天,从新复习了一遍 Promise 实现,得进去一个不算论断的论断 ……

这个题通过我的化简长成这样,求代码后果

const p = Promise.resolve()
new Promise(resolve => {new Promise(resolve => {resolve(p)})
     .then(() => {console.log('after:await')
     })
})
let p1 = p.then(() => {console.log('tick:a')
})
let p2 = p1.then(() => {console.log('tick:b')
})
let p3 = p2.then(() => {console.log('tick:c')
})
/*
p.then(() => {console.log('tick:a')
}).then(() => {console.log('tick:b')
}).then(() => {console.log('tick:c')
})
*/

promise 本质

咱们晓得 excutor 同步执行,then 外面的代码异步执行, 怎么实现的?
简略的说 (这里以胜利为例),then 外面的代码同步增加到 所属 promise的胜利回调队列,当 excutor 外面的参数 resolve 办法执行的时候,会把胜利回调队列外面的代码顺次执行

对 resolve 参数的解决

如果 excutor 的 resolve 办法承受的参数是一个 Promise 对象会怎么样?
首先我在 promiseA+ 标准外面并没有找到这种状况的规定

而后我看了三个 promise 库,bluebird,es6-promise,promise, 都没有对这种状况作解决,也就是当成一个一般的对象

最初阮一峰的 es6 外面对这种状况有形容

resolve函数的参数除了失常的值以外,还可能是另一个 Promise 实例, 这时 p1 的状态就会传递给 p2,p2 的回调函数就会期待 p1 的状态扭转

应该是新增加的 Promise 的规定

已有的材料的相干实现

在网上看了很多 Promise 实现,根本对 promise 的 excutor 的 resolve 办法的实现是这样的 promise 实现。对参数如果是 Promise 都是等 promise 执行完再调 resolve

constructor(executor){
       ...
        let resolve = (value) =>{ // 如果 resolve 的值时一个 promise
            if(value instanceof Promise){
                // 我就让这个 promise 执行,把胜利的后果再次判断
                return value.then(resolve,reject) // 参数会主动传递到 resolve 外面去
            }
            if (this.status === 'pending') {
                this.status = 'fulfilled'
                this.value = value
                this.onFulfilledCallback.forEach(fn => fn(this.value))
            }
           
        }
        ...

留神,这种实现能跑过 PromiseA+ 标准测试用例!从 A + 标准的角度没有问题

问题呈现

下面的实现相当于让咱们的题目中的 p 执行完后再 resolve,我转换一下题目局部,你们就很分明了

new Promise(resolve => {
     new Promise(resolve => {//resolve(p)
        // 相当于变成了
        p.then(resolve)
     })
     .then(() => {console.log('after:await')
     })
})

看起来很对,执行后果是
tick:a
after:await
tick:b
tick:c

然而咱们如果用原生 Promise, 理论执行后果是
tick:a
tick:b
after:await
tick:c

论断

貌似目前的 promise 在 resolve 参数解决上和 a + 标准上的不太一样
如果面试做题遇到的话, 求执行程序,如果参数是一个 Promsie 实例 i,我倡议这么解决。具体起因不晓得,晓得的大佬留言区通知我一声

var p = Promise.resolve()
new Promise(resolve => {
     new Promise(resolve => {//resolve(p)
        // 相当于变成了
        p.then().then(resolve)
     })
     .then(() => {console.log('after:await')
     })
})
退出移动版