阅读 591

手把手教你实现Promise(二)(基于Promise A+规范)

前面,我们已经实现了一个自己的Promise。但是,还有一些功能没有实现。现在就一起实现一下吧(*^ワ^*)。 

catch 

  • catch是用于指定发生错误时的回调函数。
  • catch()使回调报错时不会卡死js而是会继续往下执行。
  • Promise 对象的错误具有穿透性,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。 

用法:

let promise = new Promise((resolve, reject) => {
    reject('🙅')
})
promise.then((data) => {
    console.log(data)
}).catch(e => {
    console.log('my' + e)
})复制代码

实现思路:

我们知道then方法中,如果第一个不写对应的方法,会穿透到下一个then方法;而第二个then里,只要有reject对应的方法就可以实现。 所以这里的catch方法等于第二个then,没有写resolve对应的方法,只写了 reject对应的方法。 

 那么,我们可以在原型上添加这样的方法:

catch (fn) {
    return this.then(null, fn)
  } 复制代码

all 

Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。 

用法:

Promise.all([p1, p2, p3]).then(function(values) {
  console.log(values);
}); 复制代码
  • all()接受数组作为参数。p1,p2,p3都是Promise的实例对象,Promise要变成Resolved状态需要p1,p2,p3状态都是Resolved,如果p1,p2,p3中有一个状态是Rejected,p的状态就变成Rejected。 
  • 成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值 

实现思路:

all方法里存一个数组,然后把p1, p2, p3执行后的结果放到对应的数组里。如果有一个错误了,直接走调失败回调。

Promise.all = (promises) => {
  return new Promise((resolve, reject) => {
    let result = []; //最终返回值的结果
    let index = 0;
    let processData = (key, y) => {
      index++
      result[key] = y;
      if (promises.length === index) {
        resolve(result);
      }
    }
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(y => {
        processData(i, y);
      }, reject);
    }
  })
}复制代码

race

Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态  

用法:

Promise.race([p1, p2, p3]).then(function(value) {
  console.log(value);
}); 复制代码

实现思路: 

它跟all方法很像,但是它不需要等待其他实例执行结果,p1, p2, p3谁先执行完就执行谁的then方法。

Promise.race =(promises) => {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(resolve, reject);
    }
  })
} 复制代码

resolve 

有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。 

用法:

Promise.resolve('😄') 复制代码

实现如下:

Promise.resolve = function (data) {
  return new Promise((resolve,reject)=>{
    resolve(data);
  })
} 复制代码

reject

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

用法:

Promise.reject('❌') 复制代码

实现如下: 

Promise.reject = function (data) {
  return new Promise((resolve, reject) => {
    reject(data);
  })
} 复制代码

目前,我们就实现了一个比较完整的Promise(⌒_⌒)。



文章分类
前端