nodejs13

promise 总结

promise是异步编程的解决方案,用社区提供,标准化到ES6中。该对象中存储着某个时间才会结束的事件。

  1. 三中状态
  • pending
  • resolved
  • rejected
  • 状态一旦改变,不能再改变
  1. 缺点
  • pending时,无法知道进行到哪一种状态
  • 不可取消
  • 必须有回调函数
  1. 如果该事件经常发生,stream模式更好

延时参数传参

  1. setInterval("funName('aa')",1000); aa加单引号是字符串,不加是变量
  2. var timeoutID = window.setTimeout(func[, delay, param1, param2, ...]);
  3. 需要注意的是,IE9 及更早的 IE 浏览器不支持第二种语法中向延迟函数传递额外参数的功能。

基本用法

var promise = new Pormise(function(resolve,reject){
  if ("异步成功") {
    resolve(value);// 改变状态,哪怕多次调用,也只会执行一次
  }else {
    reject(err);
  }
});
// 使用then指定resolve和reject 的回调函数
promise.then(function(value){
  
},function(err){
  
})
  1. Promise是对象,它的实例需要创建
  2. 切换promise对象
  • p1的resolve方法调用时,参数是另一个promise实例

Promise.prototype.then可以链式编程

  1. then会返回一个新的promise 对象,不是原来的那一个。
  2. 第一个then完成以后,会将返回结果作为参数,传入第二个then
  3. 如果第一个then行完毕,返回值是promise实例,会调用第二个then的第一个函数,参数就是第一个then的返回值。
  4. 如果第一个回调函数执行完毕,返回值是promise 实例,第二个回调函数会等到自己的状态改变再执行。

Promise.prototype.catch

  1. 当一个promise实例的then既有第二个回调函数,又有catch时。当promise的状态改为reject只会执行then的第二个回调函数
  2. catch可以捕获的错误有
  • 创建promise实例时,将状态改为reject
  • 创建promise实例时的有错误,但是要在状态改为resolve之前
  • 调用resolve的回调函数,但是回调函数出错
  1. 没有使用catch方法,实例状态也没有改变时,创建实例对象中的错误不会传递到外层,即不会有任何反应。但是chrome浏览器会抛出错误。
  2. Node 有一个unhandledRejection事件,专门监听未捕获的reject错误。
//本来不会报错
var someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};

someAsyncThing().then(function() {
  console.log('everything is great');
});
//替catch行道
process.on('unhandledRejection', function (err, p) {
  console.error(err.stack)
});
  1. catch方法也可以返回一个promise对象,继续调用then。如果catch没执行,跳过catch继续执行then

promise.all

将多个promise实例包裹成一个promise实例,当所有的promise实例都变成fulfilled,或者有一个promise实例变成reject,就会触发后续函数。

promise.race

在一定时间内,被包裹的promise实例们,有一个改变就传出该promise实例。该promise实例继续调用then或者catch方法。在一定时间内没有改变,就默认为rejected状态。

promise.resolve

这是一个常用的方法,可以将很多的东西转化成promise对象。

注意:立即resolve的Promise对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。

  • 参数是promise对象,使用该方法,原样返回
  • 参数是对象并有then方法,将该对象改成promise对象,状态为resolved,立即执行then方法
  • 参数是对象但是没有then方法,或者不是对象。依旧返回该promise,立即执行then,参数就是该对象或者非对象数据
  • 无参数,返回promise对象,立即调用then方法。
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
//上面代码将jQuery生成的deferred对象,转为一个新的Promise对象。t

promise.reject

该方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

  1. 注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

超级有用的方法

使用catch结尾也不能捕获所有的错误,可以使用done来解决。下面两个方法需要自己部署

Promise.prototype.done = function (onFulfilled, onRejected) {
  this.then(onFulfilled, onRejected)
    .catch(function (reason) {
      // 抛出一个全局错误
      setTimeout(() => { throw reason }, 0);
    });
};

好处:

  • promise没有catch方法时,该方法的第二个函数可捕获
  • promise的catch中再抛出错误,也会冒泡到全局
  • promise中有catch并触发,会调用done的第一函数,代表前边都自己搞定,不需要done了

finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容