# Promise 技巧

# new Promise写法的快捷方式

1、Promise.resolve

new Promise(resolve => {
  resolve(100)
})
// 等价于(可以认为是上述代码的语法糖)
Promise.resolve(100)

// 使用方法
Promise.resolve(100).then(value => {
  console.log(value)
})

另:Promise.resolve 方法另一个作用就是将thenable对象转换为promise对象。

ES6 Promises 提到了 Thenable 这个概念,简单来说,它就是一个非常类似promise的东西。就像我们有时称具有.length方法的非数组对象为类数组(Array like)一样,thenable指的是一个具有.then方法的对象。

2、Promise.reject

new Promise((resolve, reject) => {
  reject(new Error('出错了'))
})
// 等价于(就是上述代码的语法糖)
Promise.reject(new Error('出错了'))

// 使用方法
Promise.reject(new Error('出错了')).catch(error => {
  console.error(error)
})

# Promise.all()

Promise.all接收一个promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolvereject状态的时候,它才会去调用.then方法。

也就是说:Promise的all方法提供了异步操作的能力,并且在所有异步操作执行完后才执行回调。

// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
  return new Promise(resolve => {
    setTimeout(() => {
        resolve(delay);
    }, delay);
  });
}
var startDate = Date.now();
// 所有promise变为resolve后程序退出
Promise.all([
  timerPromisefy(1),
  timerPromisefy(32),
  timerPromisefy(64),
  timerPromisefy(128)
]).then(values => {
  console.log(Date.now() - startDate + 'ms');
  // 约128ms
  console.log(values);    // [1,32,64,128]
})

这说明timerPromisefy会每隔1、32、64、128ms都会有一个promise发生resolve行为,返回一个promise对象,状态为FulFilled,其状态值为传给 timerPromisefy 的参数,并且all会把所有异步操作的结果放进一个数组中传给then

从上述结果可以看出,传递给Promise.all的promise并不是一个个的顺序执行的,而是同时开始、并行执行的。

# Promise.race()

all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,接收一个promise对象数组为参数。

Promise.all在接收到的所有的对象promise都变为FulFilled或者Rejected状态之后才会继续进行后面的处理,与之相对的是Promise.race只要有一个promise对象进入FulFilled或者Rejected状态的话,就会继续进行后面的处理。

// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
  return new Promise(resolve => {
    setTimeout(() => {
        resolve(delay);
    }, delay);
  });
}
// 任何一个promise变为resolve或reject 的话程序就停止运行
Promise.race([
  timerPromisefy(1),
  timerPromisefy(32),
  timerPromisefy(64),
  timerPromisefy(128)
]).then(function (value) {
  console.log(value);    // => 1
})

上面的代码创建了4个promise对象,这些promise对象会分别在1ms、32ms、64ms和128ms后变为确定状态,即FulFilled,并且在第一个变为确定状态的1ms后,.then注册的回调函数就会被调用,这时候确定状态的promise对象会调用resolve(1)因此传递给value的值也是1,控制台上会打印出1来。