异步篇:Promise信任问题
一. 调用过早
一个任务,它有时同步完成,有时异步完成,这可能会导致竞态条件。而 Promise 不用担心这个问题。因为:
new Promise(function(resolve){ resolve(24); // 无法被同步观察 })
-
一个立即完成的 Promise (如上例子),它无法被同步观测,意思是 Promise 调用 then(…) 的时候,即使 Promise 已经决议,提供给 then(…) 的回调也会被异步调用,不需要插入 setTimeout(…,0) 来补丁。
二. 调用过晚
Promise 创建对象调用 resolve(…) 或 reject(…) 时,Promise 回调函数的观察者就会自动调度,然后这些被调度的回调函数在下一个异步时间点上一定会被触发。例:
p.then(function(){ p.then(function(){ console.log(3) }) console.log(1) }) p.then(function(){ console.log(2) }) // 1, 2, 3
这里 ’3‘ 不会打断 ’2‘ 。因为下一个异步时间点一定会触发 then(…) 。
三. 回调未调用
有两种情况:
- 没有东西能阻止 Promise 通知决议,如果注册了一个完成回调和一个拒绝回调,Promise 总会调用其中一个。
- 如果回调函数中本身包含 JavaScript 错误,虽然看不到期望的结果,但是回调还是会被调用,其中的错误也不会吞掉。
四. 调用次数过多
Promise 创建代码视图调用 resolve(…) 或 reject(…) 多次,Promise 只会接受第一次决议,忽略任何后面的调用。所以then(…) 只能调用一次,但是如果注册了多次,就不止一次了。例( p.then(fn); p.then(fn) )。
五. 吞掉错误或异常
一般的,如果拒绝一个 Promise 并给出一个消息,这个消息就会被传递给拒绝回调函数。
- 这里把拒绝传给拒绝回调解决了一个问题,如果不传给拒绝回调,会引发同步报错,可能会导致竞态条件,而 Promise 把异常也改为了异步,避免了这种情况。