手写一个简单的promise promise是什么? promise是js异步编程的解决方案,比传统的回调函数的方式更合理和强大,完美解决回调地狱,使的异步操作更加容易
Promises/A+规范 想要编写一个完整的,规范的promise就要哦根据promises/A+规范编写
https://promisesaplus.com/英文地址
https://blog.csdn.net/qq_41800366/article/details/120788569?spm=1001.2014.3001.5501中文地址
最简单的promise使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let p = new Promise((resolve,reject)=>{ settimeOut(()=>{ if(true){ resolve('true') }else{ reject('false') } },1000) }) p.then(value => { console.log(value) // true }).catch(err => { console.log(err) // false })
写一个promise基本结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 promise是一个构造函数 new Promise传入一个函数立即执行 执行函数有resolve和reject两个参数 有一个then方法,接收两个参数 class Promise { contructor(exector){ const resolve = value => { console.log(value) } const reject = reason => { console.log(reason) } try{ exector(resolve,reject) } catch(err) { throw err } } then(arg1,arg2){ } } let p = new Promise((resolve,reject)=>{ })
promise的状态 pending,fullfilled:解决/resolved,rejected
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 三个状态 调用resolve和reject时状态要从pending变为fullfilled或者rejected const PENDING = 'pending' const FULLFILLED = 'fullfilled' const REJECT = 'rejected' class Promise { contructor(exector){ this.state = PENDING //初始pending状态 this.value = undefined this.reason = undefined this.obFullFillCallBack = undefined //保存promise内部执行的函数 this.onRejectedCallBack = undefined //保存执行的函数 const resolve = value => { if(this.state = PENDING){ this.state = FULLFILLED this.value = value this.onFUllFillCallBack && this.onFUllFillCallBack() } } const reject = reason => { if(this.state = PENDING){ this.state = REJECT this.reason = reason this.onRejectedCallBack() && this.onRejectedCallBack() } } try{ exector(resolve,reject) } catch(err) { throw err } } then(onFullfilled,onRejected //都是可选参数,如果不是函数直接忽略){ // typeof onFullfilled === 'function' && onFullfilled() // typeof onRejected === 'function' && onRejected() if(this.state === FULLFILLED){ typeof onFullfilled === 'function' && setTimeout(()=>{ onFullfilled(this.value) },0) }else if(this.state === REJECTED){ typeof onRejected === 'function' && setTimeout(()=>{ onRejected(this.reason) },0) } else { typeof onFullfilled === 'function' && (this.onFUllFillCallBack = value => { setTimeout(()=>{ onFullfilled(value) },0) }) type onRejected === 'function' && (this.onRejectedCallBack = reason => { setTimeout(()=>{ onRejected(reason) },0) } } } } let p = new Promise((resolve,reject)=>{ })
再修改一下 //最基础版Promise实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 const PENDING = 'pending' const FULLFILLED = 'fullfilled' const REJECT = 'rejected' class Promise { contructor(exector){ this.state = PENDING //初始pending状态 this.value = undefined this.reason = undefined this.obFullFillCallBacks = [] //保存promise内部执行的函数 this.onRejectedCallBacks = [] //保存执行的函数 const resolve = value => { if(this.state = PENDING){ this.state = FULLFILLED this.value = value this.onFUllFillCallBacks && this.onFUllFillCallBacks.forEach(fn => fn(value)) } } const reject = reason => { if(this.state = PENDING){ this.state = REJECT this.reason = reason this.onRejectedCallBacks && this.onRejectedCallBacks.forEach(fn => fn(reason)) } } try{ exector(resolve,reject) } catch(err) { throw err } } then(onFullfilled,onRejected //都是可选参数,如果不是函数直接忽略){ // typeof onFullfilled === 'function' && onFullfilled() // typeof onRejected === 'function' && onRejected() if(this.state === FULLFILLED){ typeof onFullfilled === 'function' && setTimeout(()=>{ onFullfilled(this.value) },0) }else if(this.state === REJECTED){ typeof onRejected === 'function' && setTimeout(()=>{ onRejected(this.reason) },0) } else { typeof onFullfilled === 'function' && (this.onFUllFillCallBack.push(value => { setTimeout(()=>{ onFullfilled(value) },0) })) type onRejected === 'function' && (this.onRejectedCallBack.push(reason => { setTimeout(()=>{ onRejected(reason) },0) }) } } } let p = new Promise((resolve,reject)=>{ })
完整版promise实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; function resolvePromise(promise, x, resolve, reject) { if (promise === x) { reject(new TypeError('Chaining cycle detected for promise')); } else if (typeof x === 'function' || (typeof x === 'object' && x !== null)) { let called = false; try { const then = x.then; if (typeof then === 'function') { then.call(x, y => { if (called) return; called = true; resolvePromise(promise, y, resolve, reject); }, r => { if (called) return; called = true; reject(r); }); } else { resolve(x); }; } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } }; class FullPromisePerfect { state = PENDING; value = undefined; reason = undefined; onFulfilledCallback = []; onRejectedCallback = []; constructor(executor) { const resolve = value => { if (this.state === PENDING) { this.state = FULFILLED; this.value = value; this.onFulfilledCallback.forEach(onFulfilled => onFulfilled(value)); } }; const reject = reason => { if (this.state === PENDING) { this.state = REJECTED; this.reason = reason; this.onRejectedCallback.forEach(onRejected => onRejected(reason)); } }; try { executor(resolve, reject); } catch (error) { reject(error); }; }; then(onFulfilled, onRejected) { const onFulfilledNow = typeof onFulfilled === 'function' ? onFulfilled : value => value; const onRejectedNow = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; const promise2 = new FullPromisePerfect((resolve, reject) => { const handleResolve = value => { try { const x = onFulfilledNow(value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); }; }; const handleReject = reason => { try { const x = onRejectedNow(reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); }; }; if (this.state === FULFILLED) { setTimeout(() => handleResolve(this.value), 0); } else if (this.state === REJECTED) { setTimeout(() => handleReject(this.reason), 0); } else { this.onFulfilledCallback.push(value => setTimeout(() => handleResolve(value), 0)); this.onRejectedCallback.push(reason => setTimeout(() => handleReject(reason), 0)); } }); return promise2; }; }; module.exports = FullPromisePerfect;
测试 想要测试写的代码,可以使用npm i promises-aplus-tests -D
随后编写测试文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 yarn add promises-aplus-tests -D 在 package.json 中添加脚本 "scripts": { "test": "promises-aplus-tests 填写测试文件地址" // 如 ./src/testFullPromise.js }, 首先在 FullPromise.js 中导出 FullPromise module.exports = FullPromise; 然后编写测试文件 const FullPromise = require('../FullPromise'); // 导入 FullPromise // 参照 promises-tests 仓库提供的方法 FullPromise.defer = FullPromise.deferred = function(){ let dfd = {}; dfd.promise = new FullPromise((resolve, reject)=>{ dfd.resolve = resolve; dfd.reject = reject; }); return dfd; }; module.exports = FullPromise; // 最后导出即可 运行命令即可开始测试 yarn test
ending