当前位置:网站首页>promise源码-class版本【三、Promise源码】【代码详细注释/测试案例完整】
promise源码-class版本【三、Promise源码】【代码详细注释/测试案例完整】
2022-06-27 03:18:00 【翼遥bingo】
JS类和对象 后续更博讲解
手撸Promise即完成promise的主要功能
- 声明构造函数
- resolve与reject
- throw抛出异常改变状态
- Promise的对象状态只能修改一次
- then方法执行回调
- 同步任务回调的执行
- 异步任务回调的执行
- 指定多个回调的实现
- 同步修改状态then方法结果返回
- 异步修改状态then方法结果返回
- Promise的API
- 构造函数: then,catch
一、 index.html
测试手撸的promise.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./promise.js"></script>
</head>
<body>
<script> let p = new Promise((resolve, reject) => {
resolve('OK'); // reject("error"); // throw "err"; setTimeout(() => {
// resolve('OK'); // reject('err'); // ............................抛出错误该咋办。。。。。。。。。。。。。。 // throw "err"; }, 1000); }); console.log(p); // p.then(value => {
// console.log(value); // }, reason => {
// console.warn(reason); // }) const res = p.then(value => {
// alert(value); return 'hello'; // return new Promise((resolve, reject) => {
// resolve("success"); // // reject("error"); // }) // throw "fail"; }, reason => {
alert(reason); }) console.log(res); let res2 = p.catch(reason => {
console.warn(reason); }) console.log(res2); // 异常穿透,值传递 p.then(value => {
// console.log(111); // throw '失败了' }).then(value => {
console.log(222); }).then(value => {
console.log(333); }).catch(reason => {
console.warn(reason); }) // resolve方法测试用例 const p1 = Promise.resolve('OK'); const p2 = Promise.resolve(new Promise((resolve, reject) => {
reject("errpr"); })); const p3 = Promise.resolve(Promise.resolve('Oh Yeah!')); console.log(p1); // reject测试用例 const r1 = Promise.reject('Error'); const r2 = Promise.reject(new Promise((resolve, reject) => {
resolve('ok') })) console.log(r1); console.log(r2); // 调用all方法 let a1 = new Promise((resolve, reject) => {
resolve('OK'); }) let a2 = Promise.resolve('Success'); let a3 = Promise.resolve('Oh Yeah'); let result3 = Promise.all([a1, a2, a3]); console.log(result3); // 调用race方法 let ra1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK'); }) }) let ra2 = Promise.reject('Successs'); let ra3 = Promise.resolve('Oh Yeah!') let result4 = Promise.race([ra1, ra2, ra3]); console.log(result4); // then方法回调的异步执行 let then1 = new Promise((resolve, reject) => {
resolve('OK'); console.log(111); }) then1.then(value => {
console.log(222); }) console.log(333); </script>
</body>
</html>
二、 promise.js【class版本】
class Promise {
// 构造方法
constructor(executor) {
// 添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 生命属性
this.callbacks = [];
const self = this;
// resolve函数
function resolve(data) {
// Promise对象状态只能修改一次
if (self.PromiseState !== 'pending') return;
// 1. 修改对象的状态(promiseState)
self.PromiseState = 'fulfilled';
// 2. 设置对象结果值(promiseResult)
self.PromiseResult = data;
// 调用成功的回调函数
// if (self.callback.onResolved) {
// self.callback.onResolved(data);
// }
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(item);
})
})
}
// reject函数
function reject(data) {
if (self.PromiseState !== 'pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = data;
// 调用失败的回调函数
// if (self.callback.onRejected) {
// self.callback.onRejected(data);
// }
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
})
})
}
try {
// 同步调用【执行器函数】
executor(resolve, reject);
} catch (e) {
// 修改Promise对象状态为失败
reject(e);
}
}
// 添加then方法
then(onResolved, onRejected) {
const self = this;
// 判断回调函数参数->异常穿透
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason;
}
}
if (typeof onResolved !== 'function') {
onResolved = value => value;
// value => { return value; }
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
// 获取回调函数的执行结果
let result = type(self.PromiseResult);
// 判断
if (result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
// 结果的对象状态为成功
resolve(result);
}
} catch (e) {
reject(e);
}
}
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved);
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected);
})
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function() {
callback(onResolved);
},
onRejected: function() {
callback(onRejected);
}
})
}
})
}
// 添加 catch方法
catch (onRejected) {
return this.then(undefined, onRejected);
}
// 添加resolve方法【属于类,而不属于实例对象】
static resolve(value) {
// 返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
resolve(value);
}
})
}
// 添加reject方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
// 添加all方法
static all(promises) {
// 返回结果为promise对象
return new Promise((resolve, reject) => {
// 声明变量
let count = 0;
let arr = [];
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++;
arr[i] = v;
if (count === promises.length) {
// 修改状态
resolve(arr);
}
}), r => {
reject(r);
}
}
})
}
// 添加 race 方法
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
// 修改返回对象的状态为[成功]
resolve(v);
}, r => {
reject(r);
})
}
})
}
}
三、 测试返回结果展示:
边栏推荐
- CVPR2021:Separating Skills and Concepts for Novel Visual Question Answering将技巧与概念分开的新视觉问答
- Microsoft365 developer request
- Pat grade a 1020 tree Traversals
- Pat grade a 1025 pat ranking
- 2021:AdaVQA: Overcoming Language Priors with Adapted Margin Cosine Loss∗自适应的边缘余弦损失解决语言先验
- NestJS环境变量配置,解决如何在拦截器(interceptor)注入服务(service)的问题
- SAI钢笔工具如何使用,入门篇
- Stack overflow vulnerability
- Easy to use plug-ins in idea
- 2022 Chinese pastry (Advanced) recurrent training question bank and online simulation test
猜你喜欢
Resnet152 pepper pest image recognition 1.0
Constraintlayout Development Guide
Learn Tai Chi maker mqtt (IX) esp8266 subscribe to and publish mqtt messages at the same time
2020:MUTANT: A Training Paradigm for Out-of-Distribution Generalizationin Visual Question Answering
Flink learning 4:flink technology stack
2021:AdaVQA: Overcoming Language Priors with Adapted Margin Cosine Loss∗自适应的边缘余弦损失解决语言先验
2021:Beyond Question-Based Biases:Assessing Multimodal Shortcut Learning in Visual Question Answeri
I found a JSON visualization tool artifact. I love it!
Learning Tai Chi Maker - mqtt (VII) advanced mqtt theme
敏捷开发篇--Agile Development-自用
随机推荐
Window 加密壳实现
测试nohup和&的各自作用
Web development framework - Express (installation and use, static hosting, routing processing, use of Middleware)
Enterprise digital transformation: informatization and digitalization
Overview of Tsinghua & Huawei | semantic communication: Principles and challenges
解决cherry pick提交报错问题
2021:adavqa: overlapping language priors with adapted margin cosine loss *
DAMA、DCMM等数据管理框架各个能力域的划分是否合理?有内在逻辑吗?
企业数字化转型:信息化与数字化
Cs5213 HDMI to VGA (with audio) single turn scheme, cs5213 HDMI to VGA (with audio) IC
QIngScan使用
人群模拟
学习太极创客 — MQTT(九)ESP8266 同时订阅和发布 MQTT 消息
TechSmith Camtasia最新2022版详细功能讲解下载
Cvpr2021:separating skills and concepts for new visual question answering
Human soberness: bottom logic and top cognition
Easy to use plug-ins in idea
Regular expressions: Syntax
TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘
2020:MUTANT: A Training Paradigm for Out-of-Distribution Generalizationin Visual Question Answering