当先锋百科网

首页 1 2 3 4 5 6 7

用途

用于处理异步操作,避免地狱式回调,比如ajax请求,处理起来更加简单方便,代码看起来也更容易理解,便于维护。

概念

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。 Promise共有三种状态,相应状态会触发相应的回调函数。

  • pending: 初始状态。什么回调函数也不触发。

    • 调用构造函数如new Promise((resolve, reject) => {}),在这个exextutor函数中要么调用resolve是状态改为完成,要么调用reject使状态改为失败,要么就什么都不调用,这个时候就是pending状态,此时[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
          
          })
      
    • .then.catch中返回值为上面直接使用构造函数的情况,并且在其内部也什么都不返回,那么这个时候也是pending

          var result = new Promise((resolve, reject) => {
              resolve('xxx')
          }).then((res) => {
              return new Promise((resolve, reject) => {
          
              })
          })
      
    • .then.catch中无返回值的时候,这个时候返回的状态为前面的Promise的状态,如果前面的状态为pending,那么这里返回的也是pending,只不过没有返回值,返回的Promise[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
              
          }).then((res) => {
      
          })
      
  • fulfilled: 成功状态。触发绑定的‘onfulfilled’方法。

    • executor函数中调用resolve

        var result = new Promise((resolve, reject) => {
            resolve('xxx')
        })
      
    • .then .catch中调用Promsie.resolve

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return Promise.resolve('bbbb')
       })
      
    • .then .catch中的返回值为一个普通值,值作为[[PromiseValue]]`的值。

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return 'xxxx'
       })
      
    • .then.catch中无返回值的时候,这个时候返回的状态为前面的Promise的状态,如果前面的状态为resolved,那么这里返回的也是resolved,只不过没有返回值,返回的Promise[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
              resolve('xxx')
          }).then((res) => {
              
          })
      
  • rejected: 失败状态。触发绑定的‘onrejected’方法。

    • executor函数中调用rejecte

        var result = new Promise((resolve, reject) => {
            reject('xxx')
        })
      
    • .then .catch中调用Promsie.reject

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return Promise.reject('bbbb')
       })
      
    • .then .catch中抛出一个错误时,状态改为rejected,并且触发onrejected函数,错误信息将作为作为拒绝状态的回调函数的参数值和拒绝状态的Promise[[PromiseValue]]的值。

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           throw 'xxxx'
       }).catch((err) => {
            console.log(err) // xxxx
       })
       console.log(result) // {[[PromiseStatus]]: "rejected",  [[PromiseValue]]: "xxxx"}
      

.then

p.then(onFulfilled, onRejected);

当状态变成成功状态的时候调用onFulfilled, 当状态变成失败的时候,调用onRejected。它返回一个Promise,而它的行为与then中的回调函数的返回值有关:

  • 如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
  • 如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
  • 如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
  • 如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
  • 如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。

Promise.resolve

参数可以是三种参数类型

  • Promise.resolve(value);
  • Promise.resolve(promise);
  • Promise.resolve(thenable);

如果参数类型是普通的值那么返回的Promise状态仍然是resolve,值为返回的值,如果返回值是另外两种情况,那么返回的Promise的状态由返回值来决定。例如下面的例子返回的是reject,值为xxxx

        var result = Promise.resolve(new Promise((resolve, reject) => {
                reject('xxxx')
        }))

Promise.reject

接收一个参数,但是参数不会影响返回的Promise结果,通过Promise.reject返回的状态始终都是reject

Promise.all

当我们需要并行执行多个异步的时候,就可以使用这个方法,该方法接收一个可以迭代的对象,例如数组,数组中一般都是我们需要并行运行的Promise对象,如果是普通值那么也会直接返回。只有每一项都为resolve时,才会调用.then中的成功方法,并且回调参数值一个包含前面所有结果的数组,并且顺序也和前面一样,否则调用失败的回调。看个例子

var a = 1
var b = new Promise((resolve, reject) => {
    setTimeout(function(){
        resolve('xxxx')
    }, 1000)
})
var c = Promise.resolve('aaa')
var result = Promise.all([a, b, c]).then((values) => {
    console.log(values) // 1, xxx, aaa
}).catch((err) => {
    console.log(err)
})

对于Promise.all的同步或者异步,如果值是空的可迭代对象,那么将是同步的,其他情况均为异步。