Promise 原理
Promise规范
要实现一个Promise必须要遵守Promise规范,Promise的规范有很多,Promise/A,Promise/B,Promise/D 以及 Promise/A 的升级版 Promise/A+。ES6 中采用了 Promise/A+ 规范。
具体的 Promise/A+ 规范可以跳转这里
Promise的实现
接下来我们就实现一个Promise
new Promise((resolve,reject)=>{setTimeout(()=>{console.log(111)resolve(222)},1000)
})
根据promise的用法,Promise的构造函数接受一个执行函数,这个函数有两个参数resolve,reject.
promise的初始状态是pending,只能由pending转变为fufilled或rejected。并且这个过程是不可逆的。
构造函数
function Promise(executor){var that = thisthis.status = 'pending' // 初始状态pendingthis.data = null // promise执行完成返回的数据或者失败的原因this.resolveCallBack = [] // promise执行成功的回调函数 this.rejectCallBack = [] // promis执行失败的回调函数//在try块中执行executor,如果有异常,则执行失败,调用rejecttry {executor(resolve,reject)} catch(e){reject(e)}
}
接下里加入resolve和reject的实现
function Promise(executor){var that = thisthis.status = 'pending' // 初始状态pendingthis.data = null // promise执行完成返回的数据或者失败的原因this.resolveCallBack = [] // promise执行成功的回调函数 this.rejectCallBack = [] // promis执行失败的回调函数function resolve(value) {if(that.status === 'pending'){ //promise的状态只能由pending转变为fufilled或rejectedthat.status = 'fufilled'that.data = valuethat.resolveCallBack.forEach((cb)=>{cb(value)})}}function reject(reason) {if(that.status === 'pending') {that.status = 'rejected' //promise的状态只能由pending转变为fufilled或rejectedthat.data = reasonthat.rejectCallBack.forEach((cb)=>{cb(reason)})}}//在try块中执行executor,如果有异常,则执行失败,调用rejecttry {executor(resolve,reject)} catch(e){reject(e)}
}
然后实现一个简易的then方法,把成功和失败的回调传入
Promise.prototype.then = function (onResolve, onReject) {this.resolveCallBack.push(onResolve);this.rejectCallBack.push(onReject);
};
一个简单的Promise就实现了,测试一下
new Promise((resolve,reject)=>{setTimeout(()=>{console.log(111)resolve(222)},1000)
}).then(function(value){console.log(value)
}
但是这样的then方法还不能实现链式调用,实际的then方法师可以多个then链式调用的。
Promise规范规定,then方法必须返回一个新的Promise以实现链式调用。
Promise.prototype.then = function(onResolve,onReject){var promise2var that = this// 判断一下传入的回调如果不是函数,生成一个默认函数把值直接返回,给下一次then调用处理onResolve = typeof onResolve === 'function' ? onResolve : function(value) {return value}onReject = typeof onReject === 'function' ? onReject : function(reason) {return reason}if(this.status === 'fufilled'){//返回一个promise对象return promise2 = new Promise(function(resolve,reject){try {// promise的状态为fufilled直接执行onResolve回调函数var x = onResolve(that.data)if(x instanceof Promise){ // then方法传入的onResolve函数也能是promise对象x.then(resolve,reject) // 所以要等传入的promise执行完毕,把then的执行结果作为promise2值返回,递归调用}resolve(x) //如果不是promise对象直接resolve返回}catch (e) {reject(e) // 出现异常执行reject}})}// 下面的rejected同理,只是执行的是onReject回调if(this.status === 'rejected'){return promise2 = new Promise(function(resolve,reject){try {var x = onReject(that.data)if(x instanceof Promise){x.then(resolve,reject)}resolve(x)}catch (e) {reject(e)}})}// 如果promise对象还没有执行完毕,是pending状态,则把回调函数放在promise的回调数组中,等执行完毕调用if(this.status === 'pending'){return promise2 = new Promise(function(resolve,reject){that.resolveCallBack.push(function(value){try {var x = onResolve(value)if(x instanceof Promise){x.then(resolve,reject)}resolve(x)}catch (e) {reject(e)}})that.rejectCallBack.push(function(value){try {var x = onReject(value)if(x instanceof Promise){x.then(resolve,reject)}resolve(x)}catch (e) {reject(e)}})})}
}
至此,一个Promise对象基本实现完毕了
顺便再实现一下promise的all
all方法首先创建一个空数组用来存储promise的返回结果,每执行完一个把结果push到results ,当数组的长度等于传入的promise个数,则所有的promise都执行完毕,resolve(results)
//
Promise.prototype.all = function(promises){var results = []return new Promise(function(resolve,reject){promises.forEach(function(promise,index){promise.then(function(value){results[index] = valueif(results.length === index+1){resolve(results)}},reject)})})
}
Promise 原理相关推荐
- 面试题promise原理
面试题Promise原理 在Promise的内部,有一个状态管理器的存在,有三种状态:pending.fulfilled.rejected. (1) promise 对象初始化状态为 pending. ...
- 从零开始,手写完整的Promise原理!
珠峰十年深度沉淀,最具诚意与深度的课程限时免费开放,带你从0到1完美诠释异步编程,并手写一个完整的promise原理! [扫码免费参加,限200人] (名额有限,扫描上方二维码立即参加!) 历史学员 ...
- js中promise原理及手动基本实现_V1
前言 这几天面试过程,有个面试官突然跟我抠上了promise的实现原理,虽然有所准备,但是没能清晰地说出其中的原理,所以有点遗憾!!!,但是事已至此,只能默默去查了相关资料深入其中了解一番.因此就有了 ...
- Promise原理详解及实现方式
在异步编程中,许多操作都会放在回调函数(callback)中,有时候需要拿到上一个异步操作的返回值再做第二次请求 比如: asyncOperation(data => {// 处理 `data` ...
- ES6 Promise原理
ES6 Promise原理 一.Promise是什么 二.为什么会有Promise 1.回调地狱 + 异步同步事件调用顺序带来的双重伤害 2.回调事件的分离 三.Promise的三种状态 1.reso ...
- promise原理与async 及 await
promise原理与async 及 await 1.1 Promise是一个构造函数 1.2 Promise优缺点 1.3 async 及 await 1.4 相较于 Promise,async/aw ...
- 简述promise原理
一. promise应用场景 1 解决回调地狱 比如我们经常可能需要异步请求一个数据之后作为下一个异步操作的入参 getData(function(a){ getMoreData(a, functio ...
- Promise原理及手写Promise
原理: Promise 原理围绕以下三个问题进行解决: (有任何一步不了解的话请先往下看手写Promise,会一步步剖析原理,看完后再继续回顾这里!!) 1. 怎么实现异步? Promise内部the ...
- Promise原理分析
前言 最近讨论到了 Promise,此前知道也使用过它,但是对于其原理却不甚了解. 于是翻了翻 MDN 上的文档,又找了几篇文章看了看,研究了研究. 最终,自己尝试了一番,对于其原理也有所了解. Pr ...
- Promise原理和使用
Promise原理和使用 Promise基本用法 嵌套的Promise 异步加载图片实例 Ajax异步操作实例 Promise新建后立即执行 promise实例作为参数 调用resolve或rejec ...
最新文章
- 深度学习的异构加速技术(一):AI 需要一个多大的“心脏”?
- redis6.0中的多线程
- 谢百三:救市后股民应牢记教训?
- 树状数组(单点+区间的所有操作)
- php xml expat,PHP Expat :XML的解析器
- flink中各种图的原理(还没搞完)
- python382怎么用_教你如何使用Python快速生成验证码
- HDU-4578 Transformation 线段树(两种方法)
- 零基础带你学习MySQL—自连接(二十一)
- 搜索引擎技术在仿冒网站检测中的应用
- bizhubc226说明书_bizhub c226驱动下载-柯尼卡美能达c226驱动下载 v1.0官方版--pc6下载站...
- vc2005运行库彻底卸载_VC2005运行库-解决方案
- YouTube视频数据分析报告
- python cplex优化包工具箱教程
- Unity 接入 ILRuntime 热更方案
- Django1.9重写用户模型报错has no attribute 'USERNAME_FIELD'
- vmware mac os 10.11.6 安装xcode 8
- ColumnTransformer()函数
- linux c++ 守护 程序,supervisor守护进程 | C/C++程序员之家
- 微信公众号运营两大痛点