手写Promise.race解析

70 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

前言

Promise.racePromise api中为数不多开发中常用的api。你能够独立实现它吗?如果还不够清晰可以和我一起通过这篇文章了解它。

阅读这篇文章,需要你掌握的知识👇

  • Promise基本知识

其中Promise基础知识如果不了解或有遗忘的同学可以参考我这篇文章:《简单明了的Promise基本知识点》

规定

Promise.race:

  • Promise.race() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set 都属于 ES6iterable类型)的输入
  • Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
  • 一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的返回值,从而异步地解析或拒绝(一旦堆栈为空)。
  • 如果传入的参数是一个空的可迭代对象,则返回的 promise 将保持等待

实现Promise.race

先创建一个函数名为myPromiseRace的函数,它接受一个promiseiterable 类型的参数👇

const myPromiseRace = function(promiseArray){
    if(Array.isArray(promiseArray)){
        
    }
}

那么参数类型不正确时应该干嘛呢?我们在参数类型不符合要求时,抛出一个错误👇

const myPromiseRace = function(promiseArray){
    if(Array.isArray(promiseArray)){
        
    }else{
        throw new Error('argument type is not iterable')
    }
}

接着,返回一个Promise实例:

const myPromiseRace = function(promiseArray){
    if(Array.isArray(promiseArray)){
        return new Promise((resolve,reject)=>{
​
        })
    }else{
        throw new Error('argument type is not iterable')
    }
}
  • 如果传入的参数是一个空的可迭代对象,则返回的 promise 将保持等待
const myPromiseRace = function(promiseArray){
    if(Array.isArray(promiseArray)){
        return new Promise((resolve,reject)=>{
             if (promiseArray.length == 0){
                //什么都不做,即不改变状态就为等待状态
              }
        })
    }else{
        throw new Error('argument type is not iterable')
    }
}
  • 一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的返回值,从而异步地解析或拒绝(一旦堆栈为空)。
function myPromiseRace(promiseArray){
    if (Array.isArray(promiseArray)){
        return new Promise((resolve, reject)=>{
            if (promiseArray.length == 0){
                //什么都不做,即不改变状态就为等待状态
            }else{
                //依次执行promise,谁先处理完就会调用对应的resolve,reject函数
                promiseArray.forEach(item =>{
                    //
                    Promise.resolve(item).then(resolve,reject)
                })
            }
        })
    }else{
        throw new Error('argument is not iterable')
    }
}

大功告成🤩

测试

用一段测试代码来测试我们的myPromiseAll👇

const promise11 = new Promise((resolve, reject) => {
    setTimeout(resolve, 300, 'one');
});
​
const promise22 = new Promise((resolve, reject) => {
    setTimeout(resolve, 200, 'two');
});
​
myPromiseRace([promise11, promise22]).then((value) => {
    console.log('fast: ', value);
});

输出

fast:  two

为什么promise22更快呢?很明显我们将它的执行函数中定时器等待的时间调的比promise11中的执行函数更快。因此符合Promise.race中,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝,且采取首个值的目标。

测试通过!

尾声

Promise.race的实现比较简单,不熟悉的同学多加练习就一定能掌握啦💪