美文网首页
js 异步系列(4)-promise下

js 异步系列(4)-promise下

作者: Super曲江龙Kimi | 来源:发表于2019-08-19 23:03 被阅读0次

promise catch

首先我们要明确其实catch就是.then(null, rejection)的语法糖。所以他仍然返回一个promise,可以继续.then执行

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

// 等同于
p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));

catch写法要比then中第二个参数要好。因为他捕获不到当前then第一个参数成功回调中的错误。

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

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

promise all

简单的promise源码实现如下:
内部会有计数器,等所有执行完毕后才会置换状态。

Promise.all = function(promise) {
  return new Promise((resolve,reject) => {
      let arr = [];
      let i = 0;
      let processData = (index, data) => {
        arr[index] = data;
        if (++i === promises.length) {
          resolve(arr);
        }
      }
      for (let i = 0; i < promises.length; i++) {
        let current = promises[i];
        if(isPromise(current)) {
          current.then(data => {
            processData(i, data);
          }, reject)
        } else {
          processData(i, current)
        }
      }
  })
}

注意点:如果promise all中的promise有自己的catch方法。则不会走all的catch方法。会返回一个新的promise,并且resolve。所以会进入all的then中而不会走catch

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

promise race

只要有一个状态改变,就马上返回。所以他的源码比all要简单。没有计数器

Promise.all = function(promise) {
  return new Promise((resolve,reject) => {
      for (let i = 0; i < promises.length; i++) {
        let current = promises[i];
        if(isPromise(current)) {
          current.then(data => {
            resolve(i, data);
          }, reject)
        } else {
          resolve(i, current)
        }
      }
  })
}

promise.race可以很多改变状态的操作,比如取消promise。或者像如下 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);

p
.then(console.log)
.catch(console.error);

promise.finally

promise.finally 的源码也很简单。执行下回调并且原值返回之前的参数

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 })
  );
};

如何终止一个promise,不要这个promise的结果,不像后传递?

new Promise(resolve => {
  resolve(new Promise(resolve=>{}));  // return一个pendding状态的promise即可
}).then(res => {console.log(res)})

如果取消一个promise

function race(p){
    let obj = {};
    // 定义一个空的promise。保存它的resolve 、reject 状态
    let p1 = new Promise(function(resolve, reject){
        obj.resolve = resolve;
        obj.reject = reject;
    });
    obj.promise = Promise.race([p, p1]);
    return obj;
}
// 需要取消时直接调用空promise的resolve即可。
// 这样race就会走成功,并且忽略掉传入的promise。达到取消的目的
 obj.resolve(cancelReason);

相关文章

网友评论

      本文标题:js 异步系列(4)-promise下

      本文链接:https://www.haomeiwen.com/subject/nlxdsctx.html