Promise 使用方法:https://www.runoob.com/w3cnote/javascript-promise-object.html

直接上代码,相关的解释都在代码的注释里面,这里以minPromise 代替 Promise:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body> <script type="text/javascript">
class minPromise {
/**
比如
var p = new minPromise ((resolve, reject)=> {
// 这里是处理的代码,脑补
})
那么 executor 就是 (resolve, reject) => { ... }
**/
constructor(executor){
// executor 必须是 function 类型
if (typeof executor !== 'function') {
throw new Error('Executor must be a function');
} // 初始状态是 PENDING
this.state = 'PENDING';
this.chained = []; const resolve = res => {
// 如果状态不是 PENDING 那就不进行处理了
if (this.state !== 'PENDING') {
return;
} // 假如说res这个对象有then的方法,我们就认为res是一个promise
if (res != null && typeof res.then === 'function') {
return res.then(resolve, reject);
} this.state = 'FULFILLED';
this.internalValue = res;
// 这里用到 解构 相当于 for(let item of this.chainer) 然后 { onFulfilled } = item , 下同
for (let { onFulfilled } of this.chained) {
onFulfilled(res);
}
}; const reject = err => {
if (this.state !== 'PENDING') {
return;
}
this.state = 'REJECTED';
this.internalValue = err;
for (const { onRejected } of this.chained) {
onRejected(err);
}
}; // 这里相当于函数初始运行 利用了构造函数自动执行的特性
try{
executor(resolve, reject);
}catch(err){
reject(err);
}
} // 状态是 FULFILLED 或者 REJECTED 说明已经执行完 resolve 方法, internalValue 也已经有值了,可以直接执行
// 状态是 PENDING 说明 resolve 的方法是异步的, 就先把 onFulfilled, onRejected 事件放到 chained 里面,存起来,等 resolve 的时候在执行 // 如果不需要then的链式调用, 用这个then就可以
// then(onFulfilled, onRejected) {
// if (this.state === 'FULFILLED') {
// onFulfilled(this.internalValue);
// } else if (this.state === 'REJECTED') {
// onRejected(this.internalValue);
// } else {
// this.chained.push({ onFulfilled, onRejected });
// }
// } // 需要then的链式调用的话 让then返回 Promise 就行
then(onFulfilled, onRejected) {
return new minPromise((resolve, reject) => {
// 这里把 onFulfilled onRejected 封装了下 是因为 resolve(onFulfilled(res)) 或者 reject(onRejected(err)) 执行的时候 有可能报错,做了错误兼容处理
const _onFulfilled = res => {
try {
//注意这里resolve有可能要处理的是一个promise
resolve(onFulfilled(res));
} catch (err) {
reject(err);
}
};
const _onRejected = err => {
try {
reject(onRejected(err));
} catch (_err) {
reject(_err);
}
};
if (this.state === 'FULFILLED') {
_onFulfilled(this.internalValue);
} else if (this.state === 'REJECTED') {
_onRejected(this.internalValue);
} else {
this.chained.push({ onFulfilled: _onFulfilled, onRejected: _onRejected });
}
});
},
// resolve方法 相当于返回一个Promise对象
resolve(value) {
return new minPromise(value => {
resolve(value);
})
},
reject(reason) {
return new minPromise((resolve, reject) => {
reject(reason);
});
},
// 全部成功的时候返回的是一个结果数组,失败的时候 会直返回失败
all(promiseArr) {
return new minPromise((res, rej) => {
// promiseArr 所有的值都看一下
var arr = [];
var times = 0;
processResult = (index, result) =>{
arr[index] = result;
times++;
// arr.length == promiseArr.length, 代表全部都 resolve 成功
if (times == promiseArr.length) {
// 在这里执行最后的 resolve
res(arr);
}
}; for (let i = 0; i < promiseArr.length; i++) {
var oPromise = promiseArr[i];
// 是 promise
if (typeof oPromise.then == 'function') {
oPromise.then((val) =>{
// then 成功后把值存下来
processResult(i, val)
}, (reason) =>{
// 不成功 直接 reject
rej(reason);
})
}else {
processResult(i, oPromise);
}
}
});
}, // 哪个实例获得结果最快,就返回那个结果,不管结果本身是成功还是失败;
race(promiseArr) {
return new minPromise((resolve, reject) => {
promiseArr.forEach((promise) => {
promise.then(resolve, reject);
});
});
}, } // 测试非链式调用
let p = new minPromise(resolve => {
setTimeout(() => resolve('Hello'), 100);
}); p.then(res => console.log(res)); p = new minPromise((resolve, reject) => {
setTimeout(() => reject(new Error('woops')), 100);
}); p.then(() => {}, err => console.log('Async error:', err.stack)); // 测试链式调用
let p2 = new minPromise(resolve => {
setTimeout(() => resolve('World'), 100);
}); p2.
then(res => new minPromise(resolve => resolve(`Hello, ${res}`))).
then(res => console.log(res)); </script> </body>
</html>

  参考:https://segmentfault.com/a/1190000014440641   ,https://juejin.im/post/5aa7868b6fb9a028dd4de672#heading-9

2020.3.11 新增:

all(promiseArr) {
let result = []
promiseArr.forEach((item, index) => { item.then(res => { result[index] = res i++ if(i === promiseArr.length) { resolve(result) } }, err => { reject(err) })
}
}

最新文章

  1. excel中的TEXT函数
  2. base64 json
  3. C++拷贝构造函数(深拷贝,浅拷贝)
  4. cocos2dx从入门到精通课程
  5. SPOJ SUBLEX 求第k小子串
  6. Oracle 查看表空间剩余与创建空间语法
  7. MVC用户登录方法(lamda表达式)
  8. shell笔记(基本知识)
  9. CodeForces 616D Longest k-Good Segment
  10. Android Imageview 图片居左居右,自定义圆角
  11. MyDAL - .IsExistAsync() 使用
  12. 读书笔记 Facebook在移动端都干了啥,居然让用户爱上广告
  13. LoRaWAN 1.1 网络协议规范 - 4 MAC 帧格式 Part II
  14. 内存优化总结:ptmalloc、tcmalloc和jemalloc(转)
  15. 解决SVN图标不显示问题
  16. OTU rank curve(Rank Abundance 曲线)【基本概念】
  17. LInux内核分析--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
  18. REX系统了解1
  19. JS 数组方法 array数组声明 元素的添加和删除 等
  20. Attribute在.net编程中的应用(一)

热门文章

  1. 014.存储过程(sql实例)
  2. HDU - 3506 Monkey Party
  3. [SCOI2016]美味——主席树+按位贪心
  4. @Configuration的使用 和作用(转)
  5. zabbix添加监控项以及常用的键值
  6. 清除文本中Html的标签
  7. sudo/su
  8. noi 统计前k大的数
  9. Eclise快捷键(最全)
  10. 初次使用自己写的testbench 验证了简单的NOT门。