博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 实现 promise
阅读量:5289 次
发布时间:2019-06-14

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

本文仅用于个人技术记录,如误导他人,概不负责。

本文有参考其他文章,不过地址忘了~~~。

 

===========================================================

上代码

const PROMISE_STATUS = {  PENDING: 'PENDING',  FULFILLED: 'FULFILLED',  REJECTED: 'REJECTED'}class ModelPromise {    static promiseId = 1;  constructor(initFn) {    if (typeof initFn !== 'function') {      throw new Error('must be function')    }        this.promiseId = ModelPromise.promiseId;    this.promiseStatus = PROMISE_STATUS.PENDING;    this.promiseValue = undefined;    this.onFulfilledStack = [];    this.onRejectStack = [];        this.finallyCallback = undefined;    initFn(this._resolve.bind(this), this._reject.bind(this));                ModelPromise.promiseId++;  }  _resolve(resolveValue) {    if (this.promiseStatus !== PROMISE_STATUS.PENDING) { return; }    const runFulfilled = (value) => {      let onFulfilled;      while (onFulfilled = this.onFulfilledStack.shift()) {        onFulfilled(value);      }            if (this.finallyCallback) {
this.finallyCallback()} } const runRejected = (error) => { let onReject; while (onReject = this.onRejectStack.shift()) { onReject(error); } if (this.finallyCallback) {
this.finallyCallback()} } const run = () => { if (resolveValue instanceof ModelPromise) { // 有父子依赖关系时候父值将由子值决定 resolveValue.then((value) => { this.promiseStatus = PROMISE_STATUS.FULFILLED; this.promiseValue = value; runFulfilled(value); }, (err) => { this.promiseStatus = PROMISE_STATUS.REJECTED; this.promiseValue = err; runRejected(err); }); } else { this.promiseStatus = PROMISE_STATUS.FULFILLED; this.promiseValue = resolveValue; runFulfilled(resolveValue); } } setTimeout(run); } _reject(err) { if (this.promiseStatus !== PROMISE_STATUS.PENDING) { return; } const run = () => { this.promiseStatus = PROMISE_STATUS.REJECTED; this.promiseValue = err; let onReject; while (onReject = this.onRejectStack.shift()) { onReject(error); } } setTimeout(run); } then(onFulfill, onReject) { let _resolveNext; let _rejectNext; /* 生成一个新的promise等待返回 */ let newPromise = new ModelPromise((resolve, reject) => { _resolveNext = resolve; _rejectNext = reject; }); const runFulfilled = value => { try { if (typeof onFulfill !== 'function') { _resolveNext(value); } else { let onFulfillReturn = onFulfill(value); if (onFulfillReturn instanceof ModelPromise) { onFulfillReturn.then(_resolveNext, _rejectNext); } else { _resolveNext(onFulfillReturn); } } } catch(err) { _rejectNext(err); } } const runRejected = error => { try { if (typeof onReject !== 'function') { _resolveNext(value); } else { let onRejectedReturn = onReject(error); if (onRejectedReturn instanceof ModelPromise) { onRejectedReturn.then(_resolveNext, _rejectNext); } else { _rejectNext(onRejectedReturn); } } } catch(err) { _rejectNext(err); } } if (this.promiseStatus === PROMISE_STATUS.FULFILLED) { runFulfilled(this.promiseValue); } else if (this.promiseStatus === PROMISE_STATUS.REJECTED) { runRejected(this.promiseValue); } else { /* important!!!! */ /* 此时推入栈中待执行的不是onFulfill, 而是runFulfilled */ /* 核心需要关注的是,当一个函数在resolve之后,应当执行then函数的回调函数并且返回值赋值给下一个promise,_resolveNext(onRejectedReturn); */ this.onFulfilledStack.push(runFulfilled); this.onRejectStack.push(runRejected); } return newPromise; } catch (catchFn) { this.then(undefined, catchFn); } finally(finallyCallback) { this.finallyCallback = finallyCallback; } static resolve(value) { // 如果需要处理的本身就是一个promise,则直接返回使用这个promise if (value instanceof ModelPromise) return value; let newPromise = new ModelPromise(resolve => { resolve(value); }); return newPromise; } static reject(value) { let newPromise = new ModelPromise(resolve, reject => { reject(value); }); return newPromise; } static race(promiseArr) { let newPromise = new ModelPromise((resolve, reject) => { promiseArr.forEach((item, index) => { if (item instanceof ModelPromise) { item.then(res => { resolve(res); checkAllResolve(); }, err => { reject(err); }); } else { resolve(item); } }); }); return newPromise; } static all(promiseArr) { let newPromise = new ModelPromise((resolve, reject) => { let promiseValArr = []; //保存所有promise的value,按顺序; const checkAllResolve = () => { if (promiseValArr.length === promiseArr.length) { resolve(promiseValArr); } } promiseArr.forEach((item, index) => { promiseValArr[index] = undefined; if (item instanceof ModelPromise) { item.then(res => { promiseValArr[index] = res; checkAllResolve(); }, err => { reject(err); }); } else { promiseValArr[index] = item; checkAllResolve(); } }); }); return newPromise; }}/* test start */let p1 = new ModelPromise((resolve, reject) => { console.log("同步执行"); setTimeout(() => { resolve('第一次resolve的值'); console.log(p1); console.log(p2); console.log(p3); console.log(p4); console.log(p5); }, 1000);});let p2 = p1.then((res) => { console.log('after then1', res); return new ModelPromise((resolve, reject) => { resolve('新promise的返回值'); });})let p3 = p2.then((res) => { console.log('after then2', res); return new ModelPromise((resolve, reject) => { setTimeout(() => { resolve('3S 后再执行的结果'); }, 3000); });});// console.log(promise1);let p4 = p1.then((res) => { console.log('接收到第一次resolve的值', res); return '第二次then的返回值';});// console.log(promise2);let p5 = p3.then((res) => { console.log('接收到第二次resolve的值', res);}).catch((err) => { console.log('捕获错误', err);});/* let promiseAll = ModelPromise.all([p1, p2, p3]).then(res => { console.log('promiseAll', res);}); */let promiseAll = ModelPromise.race([p1, p2, p3]).then(res => { console.log('promise race', res);});promiseAll.finally(() => { console.log('promiseAll finally');});

 

转载于:https://www.cnblogs.com/AlexBlogs/p/10852704.html

你可能感兴趣的文章
FTP上传下载文件
查看>>
maven build无反应,报terminated
查看>>
关于View控件中的Context选择
查看>>
【BZOJ】【1017】【JSOI2008】魔兽地图Dotr
查看>>
mediaplayer state
查看>>
C# DataTable 详解
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
扫描线矩形周长的并 POJ1177
查看>>
javascript数组
查看>>
spark_load csv to hive via hivecontext
查看>>
R语言-rnorm函数
查看>>
Spark的启动进程详解
查看>>
Java 字符终端上获取输入三种方式
查看>>
javascript 简单工厂
查看>>
oracle求时间差的常用函数
查看>>
java调用oracle存储过程,返回结果集
查看>>
使用命令创建数据库和表
查看>>
数据库的高级查询
查看>>
HttpClient(一)-- HelloWorld
查看>>
dump调试函数
查看>>