Promise源码实现

Promise使用

let promise = new Promise((resolve, reject) => {setTimeout(() => {resolve('promise')}, 1000);
})
promise.then((data) => {console.log(data)
}, (err) => {console.log(err)
})
复制代码

Promise类实现实现

class Promise {constructor(executor) {// 默认状态是等待态this.status = 'pending';this.value = undefined;this.reason = undefined;// 存放成功的回调this.onResolvedCallbacks = [];// 存放失败的回调this.onRejectedCallbacks = [];let resolve = (data) => {if (this.status === 'pending') {this.value = data;this.status = 'resolved';this.onResolvedCallbacks.forEach(fn => fn());}}let reject = (reason) => {if (this.status === 'pending') {this.reason = reason;this.status = 'rejected';this.onRejectedCallbacks.forEach(fn => fn());}}try { // 执行时可能会发生异常executor(resolve, reject);} catch (e) {reject(e); // promise失败了}}
}
复制代码

Promise原型then方法实现

class Promise {constructor(executor) {...}then(onFulFilled, onRejected) {if (this.status === 'resolved') {onFulFilled(this.value);}if (this.status === 'rejected') {onRejected(this.reason);}// 当前既没有完成 也没有失败if (this.status === 'pending') {// 存放成功的回调this.onResolvedCallbacks.push(() => {onFulFilled(this.value);});// 存放失败的回调this.onRejectedCallbacks.push(() => {onRejected(this.reason);});}}
}
复制代码
  • then方法可以返回值或者Promise, resolvePromise方法处理
function resolvePromise(promise2, x, resolve, reject) {// 判断x是不是promise// 规范里规定了一段代码,这个代码可以实现我们的promise和别人的promise可以进行交互if (promise2 === x) { // 不能自己等待自己完成return reject(new TypeError('循环引用'));}// x不是null或者是对象或者函数if (x !== null && (typeof x === 'object' || typeof x === 'function')) {let called; // 防止成功后调用失败try { // 防止取then是出现异常 Object.definePropertylet then = x.then; // 取x的then方法 {then:{}}if (typeof then === 'function') { // 如果then是函数我就认为它是promise// call 第一个参数是this ,后面的是成功的回调和失败的回调then.call(x, y => { // 如果y是promise就继续递归解析promiseif(called) return;called = true;resolvePromise(promise2,y,resolve,reject);}, r => { // 只要失败了就失败了if (called) return;called = true;reject(r);});}else{ // then是一个普通对象,就直接成功即可1resolve(x);}} catch (e) {if (called) return;called = true;reject(e);}} else { // x = 123resolve(x); // x就是一个普通值}
}
class Promise {constructor(executor) {...}then(onFulFilled, onRejected) {let promise2;if (this.status === 'resolved') {promise2 = new Promise((resolve, reject) => {// 成功的逻辑 失败的逻辑let x = onFulFilled(this.value);// 看x是不是promise 如果是promise 取他的结果 作为promise2,成功的结果// 如果要是返回一个普通值 作为promise2,成功的结果// resolvePromise可以解析x和promise2之间的关系resolvePromise(promise2, x, resolve, reject);});}if (this.status === 'rejected') {promise2 = new Promise((resolve, reject) => {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject)});}// 当前既没有完成 也没有失败if (this.status === 'pending') {// 存放成功的回调promise2 = new Promise((resolve, reject) => {this.onResolvedCallbacks.push(() => {let x = onFulFilled(this.value);resolvePromise(promise2, x, resolve, reject)});// 存放失败的回调this.onRejectedCallbacks.push(() => {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);});})}return promise2; // 调用then后返回一个新的promise}
}
复制代码
  • then方法穿透的处理
class Promise {constructor(executor) {...}then(onFulFilled, onRejected) {onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : y => y;onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };let promise2;if (this.status === 'resolved') {promise2 = new Promise((resolve, reject) => {setTimeout(() => {try {let x = onFulFilled(this.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0);});}if (this.status === 'rejected') {promise2 = new Promise((resolve, reject) => {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject)} catch (e) {reject(e);}}, 0);});}if (this.status === 'pending') {promise2 = new Promise((resolve, reject) => {this.onResolvedCallbacks.push(() => {setTimeout(() => {try {let x = onFulFilled(this.value);resolvePromise(promise2, x, resolve, reject)} catch (e) {reject(e);}}, 0)});// 存放失败的回调this.onRejectedCallbacks.push(() => {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0);});})}return promise2; // 调用then后返回一个新的promise}// catch接收的参数 只用错误catch(onRejected) {// catch就是then的没有成功的简写return this.then(null, onRejected);}
}
复制代码

Promose静态方法resolve, reject, all, race实现

Promise.resolve = function (val) {return new Promise((resolve, reject) => resolve(val))
}
Promise.reject = function (val) {return new Promise((resolve, reject) => reject(val));
}
Promise.race = function (promises) {return new Promise((resolve, reject) => {for (let i = 0; i < promises.length; i++) {promises[i].then(resolve, reject);}});
}
Promise.all = function (promises) {return new Promise((resolve,reject)=>{let arr = [];let i = 0; // i的目的是为了保证获取全部成功,来设置的索引function processData(index,data) {arr[index] = data;i++;if (i === promises.length){resolve(arr);}}for(let i = 0;i<promises.length;i++){promises[i].then(data=>{processData(i,data);}, reject);}})
}
复制代码

Promise源码实现大概就这些内容,作为学习的一个记录,希望对大家有所帮助

Promise源码实现相关推荐

  1. netty中的future和promise源码分析(二)

    前面一篇netty中的future和promise源码分析(一)中对future进行了重点分析,接下来讲一讲promise. promise是可写的future,从future的分析中可以发现在其中没 ...

  2. V8 Promise源码全面解读

    阅读本文你将收获什么? 了解 V8 Promise 源码全过程,世界上不再有能困住你的 Promise 题目,我就是这么肯定这篇文章的干货 仅仅了解或者实现了 Promise/A+ 规范,这与 Jav ...

  3. Promise源码解析

    Promise源码解析 纸上得来终觉浅,绝知此事要躬行.之前只是很浅显的知道Promise的用法,也大概猜测到它的内部是如何实现的.但是总是有一种不深究一下就不踏实的感觉.于是从npm上获得早期的Pr ...

  4. Promise源码学习(2)

    Promise源码学习(2) 本篇为上一篇源码学习(1)的补充,主要是来介绍Promise.all()和Promise.race()方法. 闲话少叙,进入正题 Promise.race() 首先来简单 ...

  5. 【手写 Promise 源码】第八篇 - 完善 Promise 并通过 promise-aplus-tests 测试

    一,前言 上一篇,实现 Promise 对返回值 x 各种情况的分析和处理,主要涉及以下几个点: 回顾了相关的 Promise A+ 规范内容: 根据 Promise A+ 规范描述和要求,实现了核心 ...

  6. Promise源码解密-Promise A+标准

    系列文章 Promise源码解密-PromisesA+标准 Promise源码解密-同步版 Promise源码解密-异步版 Promise源码解密-then的链式调用 Promise源码解密-catc ...

  7. Promise 源码:静态方法

    前言 最后来看一下 Promise 的几个常用的静态方法的实现: Promise.resolve Promise.reject Promise.all Promise.race 注:本次阅读的是 th ...

  8. 播放失败246106异常代码_web前端面试题:您能读懂的Promise源码实现(手写代码)...

    Promise 是 web 前端工程师在面试的过程中很难绕过的一个坎.如果您目前处于对 Promise 一知半解,或仅仅是停留在可以使用的层面上,建议您跟着本文敲打练习一遍,相信您一定会有所收获!另外 ...

  9. 手撕Promise源码

    日拱一卒终有尽, 功不唐捐终入海 一.Promise 类核心逻辑实现 思路: Promise 就是一个类 => 需要有一个立即执行的回调 => 传递两个参数resolve和reject(函 ...

最新文章

  1. C++ STL 基本使用Win32 版
  2. ITK:将两个图像加在一起
  3. flask和ajax通信详细步骤与完整代码
  4. r.java没有生成_R.java 常见问题(R.java文件没有生成 )
  5. android平台gallery2应用分析,Android5.1图库Gallery2代码分析数据加载流程
  6. 通过appium-desktop定位元素
  7. java excel导出 模板_Java Excel 导出 模板
  8. Javascript in one picture
  9. java error:编码gbk的不可映射字符
  10. 第一百天 how can i 坚持
  11. 终端安全求生指南(三)--脆弱性管理
  12. jsp 四大作用于和九大内置对象
  13. 智能家居至今未落地 究其原因是没想好怎么分蛋糕
  14. paip.提升安全性----Des加密 java php python的实现总结
  15. 死磕Mosek!新mosek学习笔记1:VS项目配置。
  16. 国庆回家记之2017
  17. form表单提交方式
  18. PHP开发api接口安全验证
  19. 做自媒体视频变现的三大要素!
  20. python 爬取糗百

热门文章

  1. Android GPS 取经纬度
  2. sqlserver 判断字段是否为空字符串或者null
  3. Apache Spark 2.2.0 中文文档 - Spark RDD(Resilient Distributed Datasets)
  4. OC基础15:内存管理和自动引用计数
  5. 使用BBED恢复数据文件头
  6. 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
  7. MySQL------报错Access denied for user ‘root‘@‘localhost‘ (using password:NO)解决方法
  8. 微信公众号使用LocalStorage解决返回缓存问题
  9. 【推荐算法】点击率模型特征交叉方向的发展及CAN模型介绍
  10. 【报告分享】激荡2020--吴晓波疫情特别演讲PPT.pdf(附下载链接)