两个关于Promise的坑

  • 2018-06-28
  • 115

1.Promise.race

Promise.race用于处理一般竞态问题,参数为一个迭代器可迭代对象,该对象中的任意成员状态发生改变,Promise.race返回的promise状态随即发生改变。
然而,当该对象里面没有值的情况下,Promise.race返回的promise将永远处于pending状态。
Promise.all对于空的可迭代对象则永远返回一个resolved状态的promise
此情此景类似于Array.prototype.someArray.prototype.every:
[].some(()=>{}) === false
[].every(()=>{}) === true

2.thenable

Promise.resolve 接受的参数可能为一个promise对象或其他对象,当这个对象不是Promise对象的实例时,若这个对象有then方法或其原型链上面有then方法,我们称这个对象为thenable对象,Promise.resolve内部会执行这个then方法,并传入onFulfilledonRejected两个原生函数,用于调用决定返回的Promise实例的状态。
此策略用于将jQuery.Deferred()返回的对象及其他类Promise对象转成原生Promise,然而,此举导致我们在resolve一个值时需要格外小心,这个值的原型链上面是否有自定义的then方法,比如:

Array.prototype.then = function(){}
const pro = Promise.resolve([1,23])

pro将永远处于pending状态。

要弄瘫一个现代化的网站(大量依托于Promise来实现异步逻辑),只需要一行代码:

Object.prototype.then = function(){}

而且造成的错误原因还很不好查找根源。

PS:
1.若某对象有next方法,则其可能是迭代器
2.若某对象有[Symbol.iterator]方法,则其是可迭代对象

生成器对象既是迭代器,也是可迭代对象,其[Symbol.iterator]方法执行后返回其自身