从一道Promise执行顺序的题目看Promise实现

作者:CQITer小编 时间:2018-03-14 16:10

字号
沙龙活动 | 3月31日 京东、微博实战专家与你共同探讨容器技术实践!

之前在网上看到一道Promise执行顺序的题目——打印以下程序的输出:

new Promise(resolve => { 

    console.log(1); 

    resolve(3); 

}).then(num => { 

    console.log(num) 

}); 

console.log(2) 

这道题的输出是123,为什么不是132呢?因为我一直理解Promise是没有异步功能,它只是帮忙解决异步回调的问题,实质上是和回调是一样的,所以如果按照这个想法,resolve之后应该会立刻then。但实际上并不是。难道用了setTimeout?

如果在promise里面再加一个promise:

new Promise(resolve => { 

    console.log(1); 

    resolve(3); 

    Promise.resolve().then(()=> console.log(4)) 

}).then(num => { 

    console.log(num) 

}); 

console.log(2) 

执行顺序是1243,第二个Promise的顺序会比第一个的早,所以直观来看也是比较奇怪,这是为什么呢?

Promise的实现有很多库,有jQuery的deferred,还有很多提供polyfill的,如es6-promise,lie等,它们的实现都基于Promise/A+标准,这也是ES6的Promise采用的。

从一道Promise执行顺序的题目看Promise实现

为了回答上面题目的执行顺序问题,必须得理解Promise是怎么实现的,所以得看那些库是怎么实现的,特别是我错误地认为不存在的Promise的异步是怎么实现的,因为最后一行的console.log(2)它并不是最后执行的,那么必定有某些类似于setTimeout的异步机制让上面同步的代码在异步执行,所以它才能在代码执行完了之后才执行。

当然我们不只是为了解答一道题,主要还是借此了解Promise的内部机制。读者如果有时间有兴趣可以自行分析,然后再回过头来比较一下本文的分析。或者你可以跟着下面的思路,操起鼠标和键盘和我一起干。

这里使用lie的库,相对于es6-promise来说代码更容易看懂,先npm install一下:

npm install lie 

让代码在浏览器端运行,准备以下html:

<!DOCType html> 

<html> 

<head> 

    <meta charset="utf-8"

</head> 

<body> 

    <script src="node_modules/lie/dist/lie.js"></script> 

    <script src="index.js"></script> 

</body> 

</html> 

其中index.js的内容为:

console.log(Promise); 

new Promise(resolve => { 

    console.log(1); 

    resolve(3); 

    Promise.resolve().then(()=> console.log(4)) 

}).then(num => { 

    console.log(num) 

}); 

console.log(2); 

把Promise打印一下,确认已经把原生的那个覆盖了,对比如下:

从一道Promise执行顺序的题目看Promise实现

因为原生的Promise我们是打不了断点的,所以才需要借助一个第三方的库。

我们在第4行的resolve(3)那里打个断点进去看一下resolve是怎么执行的,层层进去,最后的函数是这个:

从一道Promise执行顺序的题目看Promise实现

我们发现,这个函数好像没干啥,它就是设置了下self的state状态为FULFILLED(完成),并且把结果outcome设置为调resolve传进来的值,这里是3,如果resolve传来是一个Promise的话就会进入到上图187行的Promise链处理,这里我们不考虑这种情况。这里的self是指向一个Promise对象:

从一道Promise执行顺序的题目看Promise实现

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>Promise 执行 顺序
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接