当前位置:网站首页>手撸promise【二、Promise源码】【代码详细注释/测试案例完整】
手撸promise【二、Promise源码】【代码详细注释/测试案例完整】
2022-06-27 03:18:00 【翼遥bingo】
手撸Promise即完成promise的主要功能
- 声明构造函数
- resolve与reject
- throw抛出异常改变状态
- Promise的对象状态只能修改一次
- then方法执行回调
- 同步任务回调的执行
- 异步任务回调的执行
- 指定多个回调的实现
- 同步修改状态then方法结果返回
- 异步修改状态then方法结果返回
- Promise的API
- 构造函数: then,catch
- 函数对象: resolve,reject,all,race方法
一、 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
function Promise(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方法
Promise.prototype.then = function(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方法
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
}
// 添加resolve方法
Promise.resolve = function(value) {
// 返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
resolve(value);
}
})
}
// 添加reject方法
Promise.reject = function(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
// 添加all方法
Promise.all = function(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 方法
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
// 修改返回对象的状态为[成功]
resolve(v);
}, r => {
reject(r);
})
}
})
}
三、 测试返回结果展示:
边栏推荐
- I found a JSON visualization tool artifact. I love it!
- Uni app's uparse rich text parsing perfectly parses rich text!
- 学习太极创客 — MQTT 第二章(三)保留消息
- Learning Tai Chi Maker - mqtt Chapter 2 (II) esp8266 QoS application
- 【数组】剑指 Offer II 012. 左右两边子数组的和相等 | 剑指 Offer II 013. 二维子矩阵的和
- pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock
- Flink學習2:應用場景
- Learn Tai Chi maker mqtt (IX) esp8266 subscribe to and publish mqtt messages at the same time
- C # check whether the date is in the correct format
- Flink学习1:简介
猜你喜欢
Learn Tai Chi Maker - mqtt (VIII) esp8266 subscribe to mqtt topic
Flink学习5:工作原理
jmeter将上一个请求的结果作为下一个请求的参数
Pat grade a 1018 public bike management
Yiwen teaches you Kali information collection
[array] sword finger offer II 012 The sum of left and right subarrays is equal | sword finger offer II 013 Sum of two dimensional submatrix
Quicksand painting simulator source code
Yuantou firm offer weekly record 20220627
2021:Check it again:Progressive Visual Question Answering via Visual Entailment通过视觉暗示进行渐进式视觉问答
Web development framework - Express (installation and use, static hosting, routing processing, use of Middleware)
随机推荐
Learning Tai Chi Maker - mqtt (VII) advanced mqtt theme
Qingscan use
PAT甲级 1018 Public Bike Management
jmeter将上一个请求的结果作为下一个请求的参数
Flink learning 5: how it works
1、项目准备与新建
pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock
Anaconda3安装过程及安装后缺失大量文件,没有scripts等目录
Flink学习4:flink技术栈
ESP8266
Getting started with Scala_ Immutable list and variable list
Web development framework - Express (installation and use, static hosting, routing processing, use of Middleware)
Overview of Tsinghua & Huawei | semantic communication: Principles and challenges
2016Analyzing the Behavior of Visual Question Answering Models
TechSmith Camtasia latest 2022 detailed function explanation Download
Window 加密壳实现
Flink学习3:数据处理模式(流批处理)
2021:Beyond Question-Based Biases:Assessing Multimodal Shortcut Learning in Visual Question Answeri
解决cherry pick提交报错问题
Learn Tai Chi Maker - mqtt (VI) esp8266 releases mqtt message