JS 理解Promise的3种姿势
译者按: 对于Promise,也许你会用了,却并不理解;也许你理解了,却只可意会不可言传。这篇博客将从3个简单的视角理解Promise,应该对你有所帮助。
为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改。另外,本文版权归原作者所有,翻译仅用于学习。
示例1中,asyncFunc()
函数返回的是一个Promise实例:
1 | // 示例1 |
1秒之后,Promise实例的状态变为resolved
,就会触发then
绑定的回调函数,打印resolve
值,即”Hello, Fundebug!
“。
那么,什么是Promise呢?
- Promise调用是阻塞的
- Promise中保存了异步操作结果
- Promise是一个事件
Promise调用是阻塞的
示例2可以帮助我们理解阻塞:
1 | // 示例2 |
以上代码是采用Async/Await语法写的,与示例1完全等价。await
的中文翻译即为”等待”,这里可以”望文生义”。因此,相比于使用Promise实现,它更加直观地展示了什么是阻塞。
- (A)行: 等待
asyncFunc()
执行,直到它返回结果,并赋值给变量x
- (B)行: 打印
x
;
事实上,使用Promise实现时,也需要等待asyncFunc()
执行,之后再调用then
绑定的回调函数。因此,调用Promise时,代码也是阻塞的。
Promise中保存了异步操作结果
如果某个函数返回Promise实例,则这个Promise最初相当于一个空白的容器,当函数执行结束时,其结果将会放进这个容器。示例3通过数组模拟了这个过程:
1 | // 示例3 |
开始时,blank
为空数组,1秒之后,”Hello, Fundebug!
“被添加到数组中,为了确保成功,我们需要在2秒之后从blank
数组中读取结果。
对于Promise,我们不需要通过数组或者其他变量来传递结果,then
所绑定的回调函数可以通过参数获取函数执行的结果。
Promise是一个事件
示例4模拟了事件:
1 | // 示例4 |
调用asyncFunc()
之后,sucesss
数组其实是空的,将回调函数push
进数组,相当于绑定了事件的回调函数。1秒之后,setTimeout
定时结束,则相当于事件触发了,这时sucess
数组中已经注册了回调函数,于是打印”Hello, Fundebug!
“。
当Promise成功resolve
时,会触发then
所绑定的回调函数,这其实就是事件。