博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Promise 模拟实现
阅读量:3959 次
发布时间:2019-05-24

本文共 3397 字,大约阅读时间需要 11 分钟。

前言

最近很想研究一下Promise的原理,通过查阅资料写出了这篇博客,文章有借鉴参考文档。

正文

本文主要实现的是两个点,基本的Promisethen的链式调用。

代码的所有解释都在注释中

定义状态

//定义状态const FULFILLED = 'fulfilled'const REJECTED = 'rejected'const PENDING = 'pending'

构造函数

function MyPromise(handle) {
//this.value 是resolve或rejecte状态的值 this.value = undefined //初始化的Promise状态 this.status = PENDING //分别是成功和失败回调函数的队列 this.fulfilledCallback = [] this.rejectedCallback = [] const resolve = value => {
//只有pending状态才能被改变,reject函数同理 if (this.status === PENDING) {
//改变状态 this.status = FULFILLED //赋值给Promise的resolve状态下的值 this.value = value //执行resolve的回调函数 this.fulfilledCallback.forEach(callback => callback(value)) } } const reject = value => {
if (this.status === PENDING) {
//改变状态 this.status = REJECTED //赋值给Promise的reject状态下的值 this.value = value //执行reject的回调函数 this.rejectedCallback.forEach(callback => callback(value)) } } try {
handle(resolve, reject) } catch (err) {
reject(err) }}

then

MyPromise.prototype.then = function (onFulfilled = val=>val, onRejected = err=>{
throw err}) {
//返回一个Promise return new MyPromise((resolve, reject) => {
function handle(callback, value) {
try {
//判断then的参数是否是函数,不是则直接resolve这个新的Promise if (typeof callback !== "function") {
return resolve(value) } const result = callback(value) if (result instanceof MyPromise) {
//如果是Promsise类型,必须等待它的状态改变 result.then(resolve, reject) } else {
//then的默认状态就是resolve resolve(result) } } catch (err) {
reject(err) } } //这里的this指向是调用then的那个Promise if (this.status === FULFILLED) {
//同步任务进入 queueMicrotask(() => {
handle(onFulfilled, this.value) }) } else if (this.status === REJECTED) {
//同步任务进入 queueMicrotask(() => {
handle(onRejected, this.value) }) } else {
//异步任务 带着pending状态到这里=>注册回调函数=>等待resolve/reject来执行回调 //也就是说,如果Promise中的resolve不是异步的,根本注册不了回调函数,不会进入那两个数组 this.fulfilledCallback.push(value => {
queueMicrotask(() => {
handle(onFulfilled, value) }) }) this.rejectedCallback.push(value => {
queueMicrotask(() => {
handle(onRejected, value) }) }) } })}

实际测试

const fs = require('fs')//为了测试MyPromise,封装了一个读文件函数function readFile(path) {
return new MyPromise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) {
reject(err) } else {
resolve(data.toString()) } }) })}readFile('./a.txt') .then(data => {
console.log(data) return readFile('./b.txt') }) .then('str') .then(data => {
console.log(data) }) //先输出a文件的内容,在输出b文件的内容,成功

参考文档

结语

如果对你有帮助的话,请点一个赞吧

转载地址:http://wrozi.baihongyu.com/

你可能感兴趣的文章
牛客练习赛43——B Tachibana Kanade Loves Probability(暴力,思维)
查看>>
牛客第十七届上海大学程序设计春季联赛——E CSL 的魔法(贪心)
查看>>
杭电ACM——1028,Ignatius and the Princess III(母函数)
查看>>
杭电ACM——1171,Big Event in HDU(母函数)
查看>>
杭电ACM——6491,时间间隔(思维)
查看>>
杭电AC——1085,Holding Bin-Laden Captive!(母函数)
查看>>
杭电ACM——2110,Crisis of HDU(母函数)
查看>>
杭电AM——2152,Fruit(母函数)
查看>>
杭电ACM——2566,统计硬币(DP)
查看>>
堆栈(数据结构)
查看>>
队列(数据结构)
查看>>
杭电ACM——1251,统计难题(Trie树)
查看>>
牛客网哈尔滨工程大学第十四届程序设计竞赛(同步赛)—— 小蚂蚁过马路(思维)
查看>>
牛客网哈尔滨工程大学第十四届程序设计竞赛(同步赛)—— 苹果手链(水题)
查看>>
杭电ACM——6518,Clumsy Keke(暴力+思维)
查看>>
杭电ACM——6512,Triangle(暴力 / 思维)
查看>>
牛客网哈尔滨工程大学第十四届程序设计竞赛(同步赛)——D 简单的烦恼(DP)
查看>>
牛客网哈尔滨工程大学第十四届程序设计竞赛(同步赛)——I 杨主席发糖(思维)
查看>>
杭电ACM——1305,Immediate Decodability(Trie树)
查看>>
杭电ACM——1075,What Are You Talking About(Tire树)
查看>>