iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >图解 Promise 实现原理(四)—— Promise 静态方法实现
  • 945
分享到

图解 Promise 实现原理(四)—— Promise 静态方法实现

2023-06-03 12:06:06 945人浏览 安东尼
摘要

本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ 作者:Morrain了用法,原生提供了Promise对象。更多关于 Promi

本文首发于 vivo互联网技术 微信公众号 
链接: https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ
作者:Morrain

了用法,原生提供了Promise对象。更多关于 Promise 的介绍请参考阮一峰老师的 es6入门 之 Promise 对象。

很多同学在学习 Promise 时,知其然却不知其所以然,对其中的用法理解不了。本系列文章由浅入深逐步实现 Promise,并结合流程图、实例以及动画进行演示,达到深刻理解 Promise 用法的目的。

本系列文章有如下几个章节组成:

  1. 图解 Promise 实现原理(一)—— 基础实现

  2. 图解 Promise 实现原理(二)—— Promise 链式调用

  3. 图解 Promise 实现原理(三)—— Promise 原型方法实现

  4. 图解 Promise 实现原理(四)—— Promise 静态方法实现

一、前言

上一节中,实现了 Promise 的原型方法。包括增加异常状态,catch以及 finally。截至目前,Promise 的实现如下:

class Promise {  callbacks = [];  state = 'pending';//增加状态  value = null;//保存结果  constructor(fn) {    fn(this._resolve.bind(this), this._reject.bind(this));  }  then(onFulfilled, onRejected) {    return new Promise((resolve, reject) => {      this._handle({        onFulfilled: onFulfilled || null,        onRejected: onRejected || null,        resolve: resolve,        reject: reject      });    });  }  catch(onError) {    return this.then(null, onError);  }  finally(onDone) {    if (typeof onDone !== 'function') return this.then();     let Promise = this.constructor;    return this.then(      value => Promise.resolve(onDone()).then(() => value),      reason => Promise.resolve(onDone()).then(() => { throw reason })    );  }  _handle(callback) {    if (this.state === 'pending') {      this.callbacks.push(callback);      return;    }     let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;     if (!cb) {//如果then中没有传递任何东西      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;      cb(this.value);      return;    }     let ret;     try {      ret = cb(this.value);      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;    } catch (error) {      ret = error;      cb = callback.reject    } finally {      cb(ret);    }   }  _resolve(value) {     if (value && (typeof value === 'object' || typeof value === 'function')) {      var then = value.then;      if (typeof then === 'function') {        then.call(value, this._resolve.bind(this), this._reject.bind(this));        return;      }    }     this.state = 'fulfilled';//改变状态    this.value = value;//保存结果    this.callbacks.forEach(callback => this._handle(callback));  }  _reject(error) {    this.state = 'rejected';    this.value = error;    this.callbacks.forEach(callback => this._handle(callback));  }}

接下来再介绍一下 Promise 中静态方法的实现,譬如 Promise.resolve、Promise.reject、Promise.all 和 Promise.race。其它静态方法的实现也是类似的。

二、静态方法

1、Promise.resolve && Promise.reject

除了前文中提到的 Promise实例的原型方法外,Promise 还提供了 Promise.resolve 和Promise.reject 方法。用于将非 Promise 实例包装为 Promise 实例。例如:

Promise.resolve('foo')// 等价于new Promise(resolve => resolve('foo'))

Promise.resolve 的参数不同对应的处理也不同,如果 Promise.resolve 的参数是一个 Promise的实例,那么 Promise.resolve 将不做任何改动,直接返回这个 Promise 实例,如果是一个基本数据类型,譬如上例中的字符串,Promise.resolve 就会新建一个 Promise 实例返回。这样当我们不清楚拿到的对象到底是不是 Promise 实例时,为了保证统一的行为,Promise.resolve 就变得很有用了。看一个例子:

const Id2NameMap = {};const getNameById = function (id) {   if (Id2NameMap[id]) return Id2NameMap[id];   return new Promise(resolve => {    mockGetNameById(id, function (name) {      Id2NameMap[id] = name;      resolve(name);    })  });}getNameById(id).then(name => {  console.log(name);});

上面的场景我们会经常碰到,为了减少请求,经常会缓存数据,我们获取到 id 对应的名字后,存到 Id2NameMap 对象里,下次再通过 id 去请求 id 对应的 name 时先看 Id2NameMap里有没有,如果有就直接返回对应的 name,如果没有就发起异步请求,获取到后放到 Id2NameMap 中去。

其实上面的代码是有问题的,如果命中 Id2NameMap 里的值,getNameById 返回的结果就是 name,而不是 Promise 实例。此时 getNameById(id).then 会报错。在我们不清楚返回的是否是 Promise 实例的情况下,就可以使用 Promise.resolve 进行包装:

Promise.resolve(getNameById(id)).then(name => {  console.log(name);});

这样一来,不管 getNameById(id) 返回的是什么,逻辑都没有问题。看下面的Demo:

demo-Promise.resolve 的源码

在实现 Promise.resolve 之前,我们先看下它的参数分为哪些情况:

(1)参数是一个 Promise 实例

如果参数是 Promise 实例,那么 Promise.resolve 将不做任何修改、原封不动地返回这个实例。

(2)参数是一个 thenable 对象

thenable 对象指的是具有 then 方法的对象,比如下面这个对象。

let thenable = {  then: function(onFulfilled) {    onFulfilled(42);  }};[object Object]

Promise.resolve 方法会将这个对象转为 Promise 对象,然后就立即执行 thenable 对象的 then方法。

let thenable = {  then: function(onFulfilled) {    onFulfilled(42);  }}; let p1 = Promise.resolve(thenable);p1.then(function(value) {  console.log(value);  // 42});

上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。

(3)参数不是具有 then 方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则 Promise.resolve 方法返回一个新的 Promise 对象,状态为 resolved。

(4)不带任务参数

Promise.resolve 方法允许调用时不带参数,直接返回一个 resolved 状态的 Promise 对象。

static resolve(value) {  if (value && value instanceof Promise) {    return value;  } else if (value && typeof value === 'object' && typeof value.then === 'function') {    let then = value.then;    return new Promise(resolve => {      then(resolve);    });    } else if (value) {    return new Promise(resolve => resolve(value));  } else {    return new Promise(resolve => resolve());  }}
图解 Promise 实现原理(四)—— Promise 静态方法实现图解 Promise 实现原理(四)—— Promise 静态方法实现

--结束END--

本文标题: 图解 Promise 实现原理(四)—— Promise 静态方法实现

本文链接: https://www.lsjlt.com/news/234213.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 图解 Promise 实现原理(四)—— Promise 静态方法实现
    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ 作者:Morrain了用法,原生提供了Promise对象。更多关于 Promi...
    99+
    2023-06-03
  • Promise静态四兄弟实现示例详解
    目录前言Promise.all基础学习Iterator 接口参数思路分析源码实现Promise.allSettled基础学习思路分析源码实现Promise.race基础学习思路分析源...
    99+
    2024-04-02
  • 图解 Promise 实现原理(一)—— 基础实现
    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/UNzYgpnKzmW6bAapYxnXRQ 作者:孔垂亮很多同学在学习 Promise 时,知其然却不知其所以然,对其中的...
    99+
    2023-06-03
  • Promise+async+Generator的实现原理
    目录前言1. 观察者模式2. Promise A+规范3. then的链式调用4.值穿透 & 状态已变更的情况5.兼容同步任务Promise.prototype.catch(...
    99+
    2024-04-02
  • 如何进行Promise原型方法实现
    这篇文章给大家介绍如何进行Promise原型方法实现,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Promise 是异步编程的一种解决方案,它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Pr...
    99+
    2023-06-03
  • JavaScript实现Promise流程详解
    目录构造函数then 和 catch方法解决异步问题all和race方法构造函数 首先我们来看一下我们是如何使用promise的,我们在实例化对象是这么使用的: let p1...
    99+
    2024-04-02
  • 关于Promise基本方法的简单实现
    目录前言catch() 方法done() 方法finally() 方法Promise.all() 方法Promise.race() 方法Promise.resolve() 和 Pro...
    99+
    2024-04-02
  • C++位图的实现原理与方法
    概念 位图就是bitmap的缩写,所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,该数据都是不重复的简单数据。通常是用来判断某个数据存不存在的 例如:给40亿个不重...
    99+
    2024-04-02
  • Python地图四色原理的遗传算法着色实现
    目录1 任务需求2 代码实现2.1 基本思路2.3 结果展示总结1 任务需求   首先,我们来明确一下本文所需实现的需求。   现有一个由多个...
    99+
    2024-04-02
  • php实现后期静态绑定的方法
    这篇文章主要介绍了php实现后期静态绑定的方法,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。后期静态绑定工作原理是存储了在上一个“非转发调用”(...
    99+
    2024-04-02
  • webpack实现静态资源缓存的方法
    目录引言区分一下几种不同的hashhashchunkhashcontenthash实现js缓存CommonsChunkPlugin不正确用法引起问题的原因实现css的缓存实现图片/字...
    99+
    2024-04-02
  • 深入探索快速静态定位方法的核心原理和实现方式
    ...
    99+
    2024-01-18
    原理 实现 快速静态定位
  • 静态方法如何在Kotlin项目中实现
    本篇文章给大家分享的是有关静态方法如何在Kotlin项目中实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。工具类全都是静态方法的情况 : class 类名 改为 object...
    99+
    2023-05-31
    kotlin 静态方法 目中
  • ES6中如何实现Class类的静态方法
    这篇文章给大家分享的是有关ES6中如何实现Class类的静态方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个...
    99+
    2024-04-02
  • python静态web服务器实现方法及代码详解
    1、编写TCP服务器程序。 2、获取浏览器发送的http请求消息数据。 3、读取固定的页面数据,将页面数据组装成HTTP响应消息数据并发送给浏览器。 4、HTTP响应报文数据发送完成...
    99+
    2022-11-21
    python 静态 web服务器
  • Java方法反射实现原理详解
    博主说:Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。在本文中,占小狼分析了 J...
    99+
    2023-05-31
    java 方法反射 ava
  • 详解C++ OpenCV实现图像拼接的原理及方法
    目录前言一、图像拼接相关原理 图像特征采集特征提取算法透视变换透视矩阵图像拷贝二、案例实现Step1:导入目标图片Step2:特征点提取和匹配 Step3:图像配...
    99+
    2024-04-02
  • 代理模式:JAVA静态代理和动态代理的实例和实现详解
    目录前言静态代理实现简述创建human接口创建接口实现类创建针对接口实现增强操作的代理代理实现效果动态代理实现简述要点:向上转型创建YoungMan接口创建两个接口实现类创建动态代理...
    99+
    2024-04-02
  • 原生JavaScript轮播图实现方法
    本文实例为大家分享了JavaScript轮播图的实现方法,供大家参考,具体内容如下 效果截图: ​注:div容器大小和图片路径可以自行设置,添加img和a标签后浏览器可以...
    99+
    2024-04-02
  • Java动态代理的原理及实现方法是什么
    本篇内容主要讲解“Java动态代理的原理及实现方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java动态代理的原理及实现方法是什么”吧!代理是指:某些场景下对象会找一个代理对象,来辅助...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作