【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(课前准备)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(一、函数式编程范式)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(二、JavaScript 异步编程)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(三、手写Promise源码)
【Part1作业】https://gitee.com/zgp-qz/part01-task
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(一、ECMAScript 新特性)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(二、TypeScript 语言)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(三、JavaScript 性能优化1)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(四、JavaScript 性能优化2)
【Part2作业】https://gitee.com/zgp-qz/part02-homework
手写Promise源码
- Promise 核心逻辑实现
Promise 核心逻辑实现
-
Promise 类核心逻辑实现
-
在 Promise 类中加如异步逻辑
-
实现 then 方法多次调用,添加多个处理函数
-
实现 then 方法的链式调用
-
then 方法链式调用识别 Promise 对象自返回
-
捕获错误以及 then 链式调用其他状态码补充
-
then 方法的参数变为可选参数
-
Promise.all 方法的实现
-
Promise.resolve 方法的实现
-
finally 方法的实现
-
catch 方法的实现
首先,要先会用 Promise ,知道怎么用才能知道里面的逻辑该怎么实现:
- Promise 就是一个类 在执行这个类的时候 需要传递一个执行器进去 执行器会立即执行 - Promise 中有三种状态 分别为 成功 fulfilled 失败 rejected 等待 pending -- pending -> fulfilled -- pending -> rejected - resolve和reject函数是用来更改状态的 -- resolve: fulfilled -- reject: rejected - then方法内部做的事情就判断状态 如果状态是成功 调用成功的回调函数 如果状态是失败 调用失败回调函数 then方法是被定义在原型对象中的 - then成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败后的原因 - 同一个promise对象下面的then方法是可以被调用多次的 - then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值
// MyPromise.js /* 三个状态定义成常量,以后用的时候编辑器会有代码提示 */ const PENDING = 'pending'; // 等待 const FULFILLED = 'fulfilled'; // 成功 const REJECTED = 'rejected'; // 失败class MyPromise { constructor (executor) { try { executor(this.resolve, this.reject)} catch (e) { this.reject(e);}}// promsie 状态 默认是等待status = PENDING;// 成功之后的值value = undefined;// 失败后的原因reason = undefined;// 成功回调successCallback = [];// 失败回调failCallback = [];/* 之所以定义成箭头函数,因为调用的时候是直接调用的,如果是一个普通函数 function(){},直接调用的时候内部的 this 对象是 window 或者是 undefined,写成箭头函数让 this 对象指向当前的类 */resolve = value => { // 如果状态不是等待 阻止程序向下执行,Promise 状态是只有等待的时候才能更改if (this.status !== PENDING) return;// 将状态更改为成功this.status = FULFILLED;// 保存成功之后的值this.value = value;// 判断成功回调是否存在 如果存在 调用// this.successCallback && this.successCallback(this.value);while(this.successCallback.length) this.successCallback.shift()()}/* 之所以定义成箭头函数,因为调用的时候是直接调用的,如果是一个普通函数 function(){},直接调用的时候内部的 this 对象是 window 或者是 undefined,写成箭头函数让 this 对象指向当前的类 */reject = reason => { // 如果状态不是等待 阻止程序向下执行,Promise 状态是只有等待的时候才能更改if (this.status !== PENDING) return;// 将状态更改为失败this.status = REJECTED;// 保存失败后的原因this.reason = reason;// 判断失败回调是否存在 如果存在 调用// this.failCallback && this.failCallback(this.reason);while(this.failCallback.length) this.failCallback.shift()()}then (successCallback, failCallback) { // 参数可选successCallback = successCallback ? successCallback : value => value;// 参数可选failCallback = failCallback ? failCallback: reason => { throw reason };let promsie2 = new MyPromise((resolve, reject) => { // 判断状态if (this.status === FULFILLED) { setTimeout(() => { // 这里为了获取 promise2try { let x = successCallback(this.value);// 判断 x 的值是普通值还是promise对象// 如果是普通值 直接调用resolve // 如果是promise对象 查看promsie对象返回的结果 // 再根据promise对象返回的结果 决定调用resolve 还是调用rejectresolvePromise(promsie2, x, resolve, reject)}catch (e) { reject(e);}}, 0)}else if (this.status === REJECTED) { setTimeout(() => { // 这里为了获取 promise2try { let x = failCallback(this.reason);// 判断 x 的值是普通值还是promise对象// 如果是普通值 直接调用resolve // 如果是promise对象 查看promsie对象返回的结果 // 再根据promise对象返回的结果 决定调用resolve 还是调用rejectresolvePromise(promsie2, x, resolve, reject)}catch (e) { reject(e);}}, 0)} else { // 等待// 将成功回调和失败回调存储起来this.successCallback.push(() => { setTimeout(() => { try { let x = successCallback(this.value);// 判断 x 的值是普通值还是promise对象// 如果是普通值 直接调用resolve // 如果是promise对象 查看promsie对象返回的结果 // 再根据promise对象返回的结果 决定调用resolve 还是调用rejectresolvePromise(promsie2, x, resolve, reject)}catch (e) { reject(e);}}, 0)});this.failCallback.push(() => { setTimeout(() => { try { let x = failCallback(this.reason);// 判断 x 的值是普通值还是promise对象// 如果是普通值 直接调用resolve // 如果是promise对象 查看promsie对象返回的结果 // 再根据promise对象返回的结果 决定调用resolve 还是调用rejectresolvePromise(promsie2, x, resolve, reject)}catch (e) { reject(e);}}, 0)});}});return promsie2;}finally (callback) { return this.then(value => { return MyPromise.resolve(callback()).then(() => value);}, reason => { return MyPromise.resolve(callback()).then(() => { throw reason })})}catch (failCallback) { return this.then(undefined, failCallback)}static all (array) { let result = [];let index = 0;return new MyPromise((resolve, reject) => { function addData (key, value) { result[key] = value;index++;if (index === array.length) { resolve(result);}}for (let i = 0; i < array.length; i++) { let current = array[i];if (current instanceof MyPromise) { // promise 对象current.then(value => addData(i, value), reason => reject(reason))}else { // 普通值addData(i, array[i]);}}})}static resolve (value) { if (value instanceof MyPromise) return value;return new MyPromise(resolve => resolve(value));} }function resolvePromise (promsie2, x, resolve, reject) { if (promsie2 === x) { return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}if (x instanceof MyPromise) { // promise 对象// x.then(value => resolve(value), reason => reject(reason));x.then(resolve, reject);} else { // 普通值resolve(x);} }module.exports = MyPromise;
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(课前准备)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(一、函数式编程范式)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(二、JavaScript 异步编程)
【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(三、手写Promise源码)
【Part1作业】https://gitee.com/zgp-qz/part01-task
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(一、ECMAScript 新特性)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(二、TypeScript 语言)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(三、JavaScript 性能优化1)
【学习笔记】Part1·JavaScript·深度剖析-ES 新特性与 TypeScript、JS 性能优化(四、JavaScript 性能优化2)
【Part2作业】https://gitee.com/zgp-qz/part02-homework