起因
明天遇到一个题目,钻研了一天,从新复习了一遍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') })})