写点什么

【Promise 源码学习】第十二篇 - Promise.race 的实现

作者:Brave
  • 2021 年 12 月 05 日
  • 本文字数:1514 字

    阅读完需:约 5 分钟

一,前言


上一篇,主要实现 Promise 的核心静态 API(类方法):Promise.all,主要涉及以下几个点:


  • 测试原生 Promise.all 的使用;

  • Promise.all 的功能与特性分析;

  • Promise.all 的源码实现、执行分析、功能测试;


本篇,继续实现 Promise 静态 API(类方法):Promise.race;


备注:

  • Promise.race 与 Promise.all 实现原理相似;有了 all 的基础 race 就非常简单了;

  • Promise.race 面试高频考察点,主要用于解决超时中断问题;


二,Promise.race 简介

API 介绍


race:译为“比赛”、“赛跑”;MDN 参考资料


Promise.race功能(与 Promise.all 对比)


Promise.all

  • 批处理 promise,返回 promise;

  • 全部成功才成功,返回全部结果;

  • 一个出错就失败,返回第一个失败结果;


Promise.race

  • 批处理 promise,返回 promise;

  • 无论成功还是失败,谁快就返回谁;

2,原生 Promise.race 功能测试


let p1 = new Promise((resolve, reject) => {  setTimeout(() => {    console.log("Promise 执行完成:成功")    resolve('success')  }, 1000);})
let p2 = new Promise((resolve, reject) => { setTimeout(() => { console.log("Promise 执行完成:失败") reject('fail') }, 3000);})
Promise.race([p1, p2]).then((data) => { console.log('then', data);}).catch((err) => { console.log('catch', err);})
// 执行结果:// 1 秒后打印“Promise 执行完成:成功” + “then success”;// 3 秒后打印“Promise 执行完成:失败”;
复制代码


备注:

  • 虽然Promise.race在 1 秒后就返回了结果,但实际一共执行了 3 秒才完成;

  • 如果数组传入数字,会直接返回成功;


三,Promise.race 实现

原理分析


  • Promise.race:入参是一个 promise 集合;返回一个 Promise 实例;Promise.race 内部 return new Promise(...)

  • 执行所有 promise,使用最先返回的结果(不管成功还是失败);p.then(resolve, reject) 就看谁先进入 then;

2,代码实现


  static race (promises) {    return new Promise((resolve, reject)=>{      for(let i = 0; i < promises.length; i++){        let p = promises[i];        if(p && typeof p.then === 'function'){          p.then(resolve, reject) // 使用第一个执行成功的结果        }else{          resolve(p)        }      }    })  }
复制代码

3,功能测试


传入数字、成功/失败 promise,表现与原生 promise 一致


四,Promise.race 应用:解决超时问题


借助 Promise.race 特性,为 promise 绑个炸弹:

// 包装 promise,使之具备新功能:控制 promise 状态function wrap(p1){  let abort;  let p = new Promise((resolve, reject)=>{    // 拿到 p 的 reject,以便于随时更新 p 的状态    abort = reject;   })    // Promise.race:相当于给 p1 绑了一个定时炸弹 p  let p2 = Promise.race([p, p1]);  p2.abort = abort;// p2 就获得炸弹的遥控器                       return p2;}
复制代码


超时了,就直接引爆:

let p1 = new Promise((resolve, reject)=>{  abort = reject;  setTimeout(() => {    resolve('成功')  }, 3000);})
let p2 = wrap(p1);
p2.then((data)=>{ console.log('then', data)},(err)=>{ console.log('err', err)})setTimeout(() => { p2.abort('已超时')}, 1000);
// 执行结果:1 秒后输出"err 已超时",3 秒全部执行完成
复制代码



五,结尾


本篇,主要实现了 Promise 静态 API(类方法):Promise.race,主要涉及以下几个点:


  • 测试原生 Promise.race 的使用;

  • Promise.race 的功能与特性分析;

  • Promise.race 的源码实现、执行分析、功能测试;


下一篇,继续 Promise 静态 API:Promise.allSettledPromise.any

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第十二篇 - Promise.race 的实现