详解Promise对象

来源:互联网 发布:js数组tostring 编辑:程序博客网 时间:2024/06/09 07:35

Promise接口

es6将Promise写入语言标准,因此目前js原生支持Promise对象。使用Promise的优点就不赘述了,Promise对象起到一个代理的作用(proxy),它充当异步操作和回调函数之间的中介。它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立即返回,所以和同步流程没有区别。Promise对象使用then方法添加回调函数。then方法可以接受两个回调函数,第一个是异步操作成功时的回调函数,第二个是异步操作失败时的回调函数(可以省略)。一旦状态改变,就调用相应的回调函数。(Promise的构造函数内容下面会细讲)

   new Promise(...).then(      fn1,      fn2   )

上面代码中,Promise对象使用then方法绑定两个回调函数:操作成功时的回调函数fn1,操作失败时的回调函数fn2。这两个函数都接受异步操作传回的值作为参数。如果把这两个函数复杂化一点,伪代码就是这样

   new Promise(...).then(function(value){      ...    // 逻辑代码      console.log(value);       }, function(error){      ...    // 逻辑代码      console.log(error);   })

接下来我们来看一下Promise的具体应用例子

Promise对象生成

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由js引擎提供,不用自己部署。

   var promise = new Promise(function(resolve, reject){       //异步操作代码       if(...){       //resolve函数有两个作用,第一个是将这个对象的异步操作状态改为成功,第二个是将参数value传入回调函数           resolve(value);          } else {       //reject函数有两个作用,第一个是将这个对象的异步操作状态改为失败,第二个是将参数error传入回调函数          reject(error);       }   })

这里的value和error,是promise对象传给回调函数的参数,如果成功则传value,失败传error,所以

   var promise = new Promise(function(resolve, reject){       resolve('success')   })   promise.then(function(value){       console.log(value)   // 'success'   })

失败的时候

   var promise = new Promise(function(resolve, reject){       reject('error')   })   promise.then(function(value){       console.log(value)  //不执行,第一个函数是成功的函数   }, function(error){       console.log(error)  // 'error'     })

当然这里为了方便理解把错误处理函数写在了then中

链式调用

我们要注意,每一次调用then函数之后,返回的还是一个Promise对象

   var promise1 = new Promise(function(resolve, reject){       resolve('success')   //省略其他逻辑代码   })   promise1      .then(function(value){          console.log(value)  // 'success'          return 'success'      })      .then(function(value){          console.log(value)   // 'success'      })

这里第一个then直接返回success,相当于

   var promise1 = new Promise(function(resolve, reject){       resolve('success')   //省略其他逻辑代码   })   var promise2 = new Promise(function(resolve, reject){       resolve('success')   //省略其他逻辑代码   })   promise1      .then(function(value){          console.log(value)  // 'success'          return promise2;      })      .then(function(value){          console.log(value);   // 'success'      })

也就是说如果直接在then中return,相当于这个Promise对象的状态改为了已完成,并且把return的值传入了回调函数中。那么如果没有return一个值,那么下一个then函数自然是拿不到的

   promise1      .then(function(value){          return;      })      .then(function(value){          console.log(value);   // 'undefined'      })

那么如果发生了错误呢

   new Promise()      .then(step1)      .then(step2)      .then(step3)      .then(        console.log,        console.error      );

如果step1出错,返回的Promise对象状态为rejected,接下来的step2就不会再执行了,Promises对象开始寻找,接下来第一个操作失败时的回调函数,于是它找到了console.error,当然推荐的写法是

   promise      .then(function(data) {        // success      })      .catch(function(err) {        // error      });

catch方法可以捕获前面then方法执行中的错误,也更接近同步的写(try/catch) 需要注意的是,catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。

Promise的一次性

Promise的变化途径只有两种。

  • 异步操作从未完成到已完成
  • 异步操作从未完成到失败
    这种变化只能发生一次,一旦当前状态变为“已完成”或“失败”,就意味着不会再有新的状态变化了,所以在Promise中重复调用resolve和reject没有作用
   var promise = new Promise(function(resolve, reject){       resolve(...)       resolve(...)    // 不起作用   })
1 0
原创粉丝点击