ES2015提出了Promise,同时基于Promise的异步开发将开发者中回调地狱中解救出来。但在没有原生支持的环境下,需要借助Promise/A+之类的库来实现Promise,今天就来尝试自行实现Promise。

1 基本实现

首先来完成一个Promise类的基本框架:

function Promise(fn) {var resolveCallback = nullvar rejectCallback = nullthis.then = function(onResolved, onRejected) {resolveCallback = onResolvedrejectCallback = onRejected}this.resolve = function(value) {this.resolveCallback(value)}this.reject = function(reason) {this.rejectCallback(reason)}fn(this.resolve, this.reject)
}

以上便是Promise的基本实现。

2 状态管理

上述的代码存在一个问题,resolve方法会调用多次,所以接下来我们需要接入状态管理。

Promise内部存在3个状态:

  • pending
  • resolved
  • rejected

接下来在现有代码之上,加入状态管理:

function MyPromise(fn) {let state = 'pending'var resolveCallback = nullvar rejectCallback = nullvar childResolvevar childRejectthis.then = function(onResolved, onRejected) {resolveCallback = onResolvedrejectCallback = onRejected}this.resolve = function(value) {if(state === 'pending') {this.resolveCallback(value)state = 'resolved' } }this.reject = function(reason) {if(state === 'pending') {this.rejectCallback(reason)state = 'rejected'}   }fn(this.resolve, this.reject)
}

3 链式调用

上述Promise实现可以完成正常的异步调用,但是却无法实现链式回调,原因在于其then方法没有返回一个新的Promise对象,所以接下来还需要改造then方法,实现链式调用:

  this.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {......})}

光返回一个promise对象还没用,接下来我们来写个demo测试下:

  var demo = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('my first promise')}, 1000)})demo.then((msg) => {console.log(msg)return 'my second promise'}).then((msg) => {console.log(msg)})

其输出为:

my first promise

事实上,第二个promise对象的resolve reject方法从未被调用过,因而其onResolved onRejected的回调ye就无从调用。所以还必须指定时机调用字promise对象的resolvereject

所以首先需要在创建新promise对象时,记录其resolvereject方法:

function MyPromise() {......var childResolvevar childRejectthis.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {childResolve = resolvechildReject = reject})}
}

接下来还需在resolvereject方法中调用子对象的resolvereject方法,整个Promise完整代码如下:

function MyPromise(fn) {let state = 'pending'var resolveCallback = nullvar rejectCallback = nullvar childResolve = nullvar childReject = nullthis.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {childResolve = resolvechildReject = reject})}this.resolve = function(value) {if(state === 'pending') {if(resolveCallback) {var ret = resolveCallback(value)childResolve(ret)state = 'resolved' }} }this.reject = function(reason) {if(state === 'pending') {if(rejectCallback) {var ret = rejectCallback(reason)childReject(ret)state = 'rejected'}}   }fn(this.resolve, this.reject)}

JavaScript之Promise实现相关推荐

  1. JavaScript 的 Promise  和  C# 的 waitone 一样吗?请大家讨论i两句。

    JavaScript 的 Promise  和  C# 的 waitone 一样吗?请大家讨论i两句.

  2. JavaScript之Promise

    看完下面文章,你将了解到: 1.什么是Promise? 2.Promise怎样使用以及使用的场景,解决了什么问题 3.ES7较ES6又增加了哪些支撑Promise的语法糖 复制代码 一.Promise ...

  3. 实现 JavaScript 异步方法 Promise.all

    本次的任务 假如..... JavaScript v8 引擎发生了重大故障,Promise.all 方法变成了 undefined ,为了拯救 JavaScript 世界,需要开发一个模块来解决此问题 ...

  4. 你真的了解JavaScript的Promise吗?

    什么是Promise Promise代理了一个可能要在未来才能到达的值[[PromiseValue]].Promise的一个最重要的特点是,你可以通过then来指定当[[PromiseValue]]到 ...

  5. javascript的promise

    'use strict'; // ajax函数将返回Promise对象: function ajax(method, url, data) {var request = new XMLHttpRequ ...

  6. Javascript ES6 Promise同步读取文件(使用async、await)

    const fs=require('fs'); const path=require('path');const dirname='D:\\HBuilderX\\Workspace\\NodeJS\\ ...

  7. Javascript ES6 Promise异步链式读取文件解决回调地狱

    const fs=require('fs'); const path=require('path');const dirname='D:\\HBuilderX\\Workspace\\NodeJS\\ ...

  8. JavaScript:Promise进阶知识

    Promise Promise就是ES6新增的一个用于解决异步编程的方案.以前,我们在处理异步的时候,都是在回调函数内做处理的.比如Ajax请求,是在success属性里面做异步处理的,那么如果在一个 ...

  9. 学习笔记 JavaScript ES6 Promise的静态方法

    学习内容: Promise.resolve() Promise.reject() Promise.all() Promise.race() Promise.resolve(),表示成功的状态 Prom ...

最新文章

  1. python中内置的四种数值类型为_浅谈python语言四种数值类型
  2. 步进电机正反转实验_电工基础:帮你学会电机正反转双重互锁控制
  3. app服务器一种什么样的服务器
  4. c51语言定义全局变量,全局变量的定义和使用
  5. 13个AJAX验证框架
  6. 第 3 章 第 2 题 求级数问题 递归法实现
  7. Netty权威指南之伪异步I/O编程
  8. 关于winodows下编程c++遇到的引用文件路径问题
  9. HSRPSTPACL
  10. 国科大高级人工智能5-RNN/LSTM/GRU/集束搜索/attention
  11. kax格式怎么导入不了pr_pr如何导入.mogrt文件 pr模板导入教程
  12. php mysql登陆页面完整代码_求助:PHP实现登陆注册的代码是什么啊(主要是数据库那块)?...
  13. 阿里云服务器如何修改密码
  14. Python基础—文件操作
  15. Shiro保姆级教程
  16. IPhone手机无法连接蓝牙
  17. 调研主板,树莓派 VS RK3288板子,还是 RK的主板香,但是只支持 anrdoid 7系统,估计也有刷机成 armbian或者
  18. Allegro PCB Design GXL (legacy) - 铺网格铜
  19. matlab 求曲面体积,matlab求两曲面之间的体积
  20. 网络七层协议:OSI七层协议大白话解读

热门文章

  1. 研究人员吐槽当前AI训练效率过于低下
  2. 「走过」微软、优步,老工程师告诉你哪些数据结构和算法最重要
  3. SAP MM 公司间STO里交货单PGI之后自动触发内向交货单功能的实现
  4. 「机器学习」彻底搞懂CNN
  5. 《数学之美》第15章 矩阵运算和文本处理中的两个分类问题
  6. windows如何禁止onenote自启
  7. 世界机器人大会|人工智能VS人类
  8. 揭秘5G+AI时代的机器人世界!七大核心技术改变人类生活
  9. Science | 闵明玮等揭示细胞如何做出命运决定
  10. 5G新标准将延迟3个月发布,但5G“新战场”已经明确