当前位置:网站首页>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);
})
}
})
}
}
三、 测试返回结果展示:

边栏推荐
- Flink learning 2: application scenarios
- Cvpr2021:separating skills and concepts for new visual question answering
- 一文教你Kali信息收集
- pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock
- QIngScan使用
- mmdetection ValueError: need at least one array to concatenate解决方案
- Quicksand painting simulator source code
- Learning Tai Chi Maker - mqtt Chapter 2 (II) esp8266 QoS application
- paddlepaddle 20 指数移动平均(ExponentialMovingAverage,EMA)的实现与使用(支持静态图与动态图)
- SAI钢笔工具如何使用,入门篇
猜你喜欢

Pat grade a 1019 general palindromic number

2021:Greedy Gradient Ensemble for Robust Visual Question Answering

【一起上水硕系列】Day 6

解决cherry pick提交报错问题

PAT甲级 1021 Deepest Root

jmeter将上一个请求的结果作为下一个请求的参数

2021:Check it again:Progressive Visual Question Answering via Visual Entailment通过视觉暗示进行渐进式视觉问答

事业观、金钱观与幸福观

Flink learning 2: application scenarios

pytorch_grad_cam——pytorch下的模型特征(Class Activation Mapping, CAM)可视化库
随机推荐
2021:passage retrieval for outside knowledgevisual question answering
Anaconda3安装过程及安装后缺失大量文件,没有scripts等目录
学习太极创客 — MQTT 第二章(二)ESP8266 QoS 应用
Flink学习3:数据处理模式(流批处理)
剑指Offer || :栈与队列(简单)
Flink learning 1: Introduction
Flink learning 4:flink technology stack
Super detailed, 20000 word detailed explanation, thoroughly understand es!
2022茶艺师(高级)上岗证题库模拟考试平台操作
Super détaillé, 20 000 caractères détaillés, mangez à travers es!
我是怎样简化开源系统中的接口的开发的?
【微服务|Sentinel】降级规则|慢调用比例|异常比例|异常数
Mmdetection uses yolox to train its own coco data set
2020:MUTANT: A Training Paradigm for Out-of-Distribution Generalizationin Visual Question Answering
TechSmith Camtasia最新2022版详细功能讲解下载
PAT甲级 1024 Palindromic Number
Learn Tai Chi maker mqtt (IX) esp8266 subscribe to and publish mqtt messages at the same time
PAT甲级 1026 Table Tennis
mmdetection 用yolox训练自己的coco数据集
The use and introduction of pytorch 23 hook and the implementation of plug and play dropblock based on hook