手写Promise then/catch/resolve/reject all/allSetteld

2023-10-13 04:38

本文主要是介绍手写Promise then/catch/resolve/reject all/allSetteld,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原生

    <script>const promise = new Promise((resolve, reject) => {resolve();// reject();});console.log(promise);</script>//Promise是一个构造函数
//参数为一个函数,且同步自调用了(这里称它为executor)
//executor中传入了两个函数,分别是resolve和reject,用来改变promise的状态
//promise的初始状态为pending
//promise的状态只能修改一次

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

MyPromise.prototype

实现resolve/reject

(function (w) {function MyPromise(executor) {// promise对象就是this,这是因为new关键字作用const that = this;/* 初始化promise对象是pending状态_开头的属性是私有属性,外界不允许操作*/that._status = "pending";// resolve函数将promise对象状态改成resolvedfunction resolve() {// 让promise对象状态只能修改一次if (that._status !== "pending") return;// 如果不用that,这里的this指向是有问题的that._status = "resolved";}// reject函数将promise对象状态改成rejectedfunction reject() {if (that._status !== "pending") return;that._status = "rejected";}// 同步调用executor(resolve, reject);}w.MyPromise = MyPromise;
})(window);
  • html
  <body><script src="./01.promise.js"></script><script>const promise = new MyPromise((resolve, reject) => {resolve();// reject()});console.log(promise);</script></body>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实现then方法–基础

promise.then(
(value) => { },
(reason) => { }
)
1.then方法是promise实例对象使用的,所以定义在原型上
2.then方法是同步执行的
3.第一个参数是成功的回调,第二个参数是失败的回调
4.回调中可以接收到promise的结果值

  • 当原型添加了then方法时,会将onResolve和onReject通过this传到promise实例对象身上
  • 而在MyPromise构造函数中,通过that(这里替换了this,也是指向promsie实例对象)拿到这两个方法,在resolve和reject中调用
  • onResolve和onReject都是异步函数
(function (w) {function MyPromise(executor) {const that = this;that._status = "pending";// 用来存储成功/失败回调函数的容器that._callbacks = {};function resolve(value) {if (that._status !== "pending") return;that._status = "resolved";// 触发和调用onResolved函数,切记这里要异步去调用,因为代码同步执行的,这个时候原型上还没有添加这些方法setTimeout(() => {// that._callbacks.onResolved && that._callbacks.onResolved(value);// 这个和上面的写法一样,但是是ES11的语法,2020年  新的运算符?.可选链that._callbacks.onResolved?.(value);}, 0);}function reject(error) {if (that._status !== "pending") return;that._status = "rejected";// 如果不用定时器,这样子也可以that._callbacks.onRejected && that._callbacks.onRejected(error);}executor(resolve, reject);}MyPromise.prototype.then = function (onResolved, onRejected) {/* this指向实例对象promise将成功/失败回调添加到容器中(注意没有调用,只是去添加这个属性,在调用回调的时候执行)在Promise原型上添加then方法,方法中也是两个函数作为参数,分别是成功的回调和失败的回调*/this._callbacks.onResolved = onResolved;this._callbacks.onRejected = onRejected;};w.MyPromise = MyPromise;
})(window);
  <body><script src="./01.promise.js"></script><script>const promise = new MyPromise((resolve, reject) => {resolve(123);// reject(777);});console.log(promise);promise.then((value) => {console.log("then方法成功回调---->" + value);},(error) => {console.log("then方法失败回调---->" + error);});</script></body>

在这里插入图片描述

在这里插入图片描述

  • 没有解决异步
    在这里插入图片描述

then方法返回值/三种

  • 调用then方法需要返回一个promise对象
  • 因为promise的状态只能改变一次,所以我们需要返回一个新的promise对象
    1.当then方法没有返回值,或者有返回值但不是promise对象时,默认返回一个新的成功的promise对象
    2.当then方法返回一个promise对象需要判断是成功还是失败的peomsie对象
    3.当then方法调用时,内部报错,需要返回一个失败的peomise对象
(function (w) {function MyPromise(executor) {const that = this;that._status = "pending";// 定义promise默认返回值that._result = undefined;that._callbacks = {};function resolve(value) {if (that._status !== "pending") return;that._status = "resolved";// 修改promise的返回值that._result = value;setTimeout(() => {that._callbacks.onResolved?.(value);});}function reject(error) {if (that._status !== "pending") return;that._status = "rejected";// 修改promise的返回值that._result = error;setTimeout(() => {that._callbacks.onRejected && that._callbacks.onRejected(error);});}executor(resolve, reject);}MyPromise.prototype.then = function (onResolved, onRejected) {const that = this;// 调用then方法,返回一个新的promise对象,这样才能实现then方法的链式调用return new MyPromise((resolve, reject) => {// then的返回值,取决于内部函数的返回值,怎么拿到这个函数内部返回值呢?小技巧that._callbacks.onResolved = function (value) {const resolvedRES = onResolved(value);// 如果res的隐式原型在MyP的显示原型上,其实就是确认是peomise实例if (resolvedRES instanceof MyPromise) {resolvedRES.then(resolve, reject);/* 实际这个是这样的简写result.then((value) => resolve(value),(reason) => reject(reason));*/} else {// 说明没有返回值或者返回值不是promiseresolve(resolvedRES);}};// 其实和resolve返回机制一样this._callbacks.onRejected = function (error) {const rejectedRES = onRejected(error);if (rejectedRES instanceof MyPromise) {rejectedRES.then(resolve, reject);} else {resolve(rejectedRES);}};});};w.MyPromise = MyPromise;
})(window);
  • html
  <body><script src="./02.promise.js"></script><script>const promise = new MyPromise((resolve, reject) => {// resolve(123);reject(777);});console.log(promise);promise.then((value) => {console.log("then方法成功回调---->" + value);},(error) => {return 50765console.log("then方法失败回调---->" + error);}).then((value) => {console.log("then2方法成功回调---->" + value);},(error) => {console.log("then2方法失败回调---->" + error);});</script></body>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

then方法返回值报错解决

  • 就是在上面代码加了try catch而已
(function (w) {function MyPromise(executor) {const that = this;that._status = "pending";that._result = undefined;that._callbacks = {};function resolve(value) {if (that._status !== "pending") return;that._status = "resolved";that._result = value;setTimeout(() => {that._callbacks.onResolved?.(value);});}function reject(error) {if (that._status !== "pending") return;that._status = "rejected";that._result = error;setTimeout(() => {that._callbacks.onRejected && that._callbacks.onRejected(error);});}executor(resolve, reject);}MyPromise.prototype.then = function (onResolved, onRejected) {const that = this;return new MyPromise((resolve, reject) => {that._callbacks.onResolved = function (value) {// 加入了try tachtry {const resolvedRES = onResolved(value);if (resolvedRES instanceof MyPromise) {resolvedRES.then(resolve, reject);} else {resolve(resolvedRES);}} catch (error) {reject(error);}};this._callbacks.onRejected = function (error) {try {const rejectedRES = onRejected(error);if (rejectedRES instanceof MyPromise) {rejectedRES.then(resolve, reject);} else {resolve(rejectedRES);}} catch (error) {reject(error);}};});};w.MyPromise = MyPromise;
})(window);

在这里插入图片描述

实现catch

  • 借用then方法功能
  // 在then方法函数中结局catch的报错// // 为了then方法不传第二个函数(失败回调)服务onRejected =typeof onRejected === "function"? onRejected: (error) => {throw error;};//  为了catch方法不传第一个回调服务onResolved =typeof onResolved === "function" ? onResolved : (value) => value;
// catch实际就是借用了then的方法MyPromise.prototype.catch = function (onRejected) {return this.then(undefined, onRejected);};
  • 不带try catch的报错
    在这里插入图片描述
    在这里插入图片描述
  • 带try catch的报错
    在这里插入图片描述
   <body><script src="./02.promise.js"></script><script>const promise = new MyPromise((resolve, reject) => {resolve ();// reject(777);});console.log(promise);promise.then((value) => {console.log(11111, value);})// catch还是会执行,匹配的时候上一次是成功的,然后catch接收这个成功promise,是undefined,调用onResulved调用resolve报错.catch((err) => {console.log(22222, err);}).then((value) => {console.log(33333, value);}).catch((reason) => {console.log(4444, reason);});</script></body>
  • 解决之后不会有报错
    在这里插入图片描述

MyPromise方法:

resolve

  // 给promise添加一个resolve方法MyPromise.resolve = function (value) {if (val instanceof MyPromise) {return value;}return new MyPromise((resolve) => resolve(value));};

reject

  // 给promise添加一个reject方法MyPromise.reject = function (reason) {return new MyPromise((resolve, reject) => reject(reason));};

all

  • 优化版
  // all方法所有成功返回成功promise,有一个失败返回失败promise,失败的值就是第一个失败的值MyPromise.all = function (promises) {// 定义一个数组,用来保存成功的promiseconst result = [];// 传入数组的长度const total = promises.length;// 已经完成的数量let completeNum = 0;// 调用all方法会返回一个新的promise,all方法接收一个数组return new MyPromise((resolve, reject) => {// 去遍历这个传入的数组promises.forEach((item, index) => {if (item instanceof MyPromise) {item.then((value) => {// result[index] = value;// completeNum++;// if (total === completeNum) {//   resolve(result);// }Common(index, value);},// 这个方法是简写,完整版见下面reject);} else {// result[index] = item;// completeNum++;// if (total === completeNum) {//   resolve(result);// }Common(index, item);}});// 不能定义在forEach 否则每次都会创建这个函数function Common(index, value) {result[index] = value;completeNum++;if (total === completeNum) {resolve(result);}}});};
  • 基础版
  // all方法所有成功返回成功promise,有一个失败返回失败promise,失败的值就是第一个失败的值MyPromise.all = function (promises) {// 定义一个数组,用来保存成功的promiseconst result = [];// 传入数组的长度const total = promises.length;// 已经完成的数量let completeNum = 0;// 调用all方法会返回一个新的promise,all方法接收一个数组return new MyPromise((resolve, reject) => {// 去遍历这个传入的数组promises.forEach((item, index) => {if (item instanceof MyPromise) {item.then((value) => {result[index] = value;completeNum++;if (total === completeNum) {resolve(result);}},(reason) => reject(reason));} else {result[index] = item;completeNum++;if (total === completeNum) {resolve(result);}}});});};
      // 注意这里要写自定义的promise,否则不会进入判断,直接renturn这个promise到数组const p = new MyPromise((resolve) => resolve(777));// const f = new MyPromise((resolve, reject) => reject(9999));const res = MyPromise.all([111, 222, 333,p]);console.log(res)

在这里插入图片描述
在这里插入图片描述

allSetteld

  /* 只要里边的promise对象没有执行完成,则allSettled返回pending状态的promise对象只要里边的promise对象全部完成了,则allSettled返回fulfilled状态的promise对象(无论是否所有的promise都失败了)当所有的请求完成,allSettled的状态值就是成功,allSettled的value就是一个数组,包含了所有的方法内返回promise对象*/MyPromise.allSetteld = function (promises) {// 调用allSetteld方法,返回一个promisereturn new MyPromise((resolve) => {// 声明一个数组,保存成功的值const result = [];// 得到传入数组的数量const total = promises.length;// 已经完成的数量let completeNum = 0;promises.forEach((item, index) => {if (item instanceof MyPromise) {item.then((value) => {result[index] = {status: "resolved",value,};completeNum++;if (total === completeNum) {resolve(result);}},(reason) => {result[index] = {state: "rejected",reason,};completeNum++;if (total === completeNum) {resolve(result);}});} else {result[index] = {state: "resolved",value: item,};completeNum++;if (total === completeNum) {resolve(result);}}});});};
      const p = new MyPromise((resolve) => {setTimeout(() => {  resolve(777);}, 2000);});const f = new MyPromise((resolve, reject) => reject(9999));const res = MyPromise.allSetteld([111, 222, 333, p, f]);console.log(res);setTimeout(()=>{console.log(res)},3000)

在这里插入图片描述

这篇关于手写Promise then/catch/resolve/reject all/allSetteld的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/200806

相关文章

C++第四十七弹---深入理解异常机制:try, catch, throw全面解析

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】 目录 1.C语言传统的处理错误的方式 2.C++异常概念 3. 异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3 异常安全 3.4 异常规范 4.自定义异常体系 5.C++标准库的异常体系 1.C语言传统的处理错误的方式 传统的错误处理机制:

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

JS手写实现深拷贝

手写深拷贝 一、通过JSON.stringify二、函数库lodash三、递归实现深拷贝基础递归升级版递归---解决环引用爆栈问题最终版递归---解决其余类型拷贝结果 一、通过JSON.stringify JSON.parse(JSON.stringify(obj))是比较常用的深拷贝方法之一 原理:利用JSON.stringify 将JavaScript对象序列化成为JSO

T1打卡——mnist手写数字识别

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 1.定义GPU import tensorflow as tfgpus=tf.config.list_physical_devices("GPU")if gpus:gpu0=gpus[0]tf.config.experimental.set_memort_groth(gpu0,True) #设置GPU现存用量按需

try -catch-finally的理解,同时在try-catch-finally中含有return和throws的理解

在没有try-catch或try-catch-finally的情况下,程序正常执行到某行,在这行报错后,这行后面的代码就不执行了,程序就停止了,中断了。 例如   在有try-catch或try-catch-finally 情况上,在某行执行错误,在try中这行下的代码不执行,try外的代码执行。当然是catch在没有做处理的情况下。如果catch中做了处理,在不影响当前程序下,try

【JavaScript】异步操作:Promise对象

文章目录 1 概述2 Promise 对象的状态3 Promise 构造函数4 Promise.prototype.then()5 then() 用法辨析6 微任务 1 概述 Promise 对象是 JavaScript 的异步操作解决方案,为异步操作提供统一接口。它起到代理作用,充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。 Promise 的设计思想是,

Promise的使用总结

Promise 是 JavaScript 中用于处理异步操作的一种机制。它提供了一种更清晰和更简洁的方式来处理异步代码,避免了回调地狱。以下是 Promise 的使用方法,包括创建 Promise、链式调用、错误处理、并行执行等。 1. 创建 Promise 你可以使用 new Promise 来创建一个新的 Promise 对象。Promise 构造函数接受一个执行函数,该函数有两个参数:r

【DL--22】实现神经网络算法NeuralNetwork以及手写数字识别

1.NeuralNetwork.py #coding:utf-8import numpy as np#定义双曲函数和他们的导数def tanh(x):return np.tanh(x)def tanh_deriv(x):return 1.0 - np.tanh(x)**2def logistic(x):return 1/(1 + np.exp(-x))def logistic_derivati

【tensorflow CNN】构建cnn网络,识别mnist手写数字识别

#coding:utf8"""构建cnn网络,识别mnistinput conv1 padding max_pool([2,2],strides=[2,2]) conv2 x[-1,28,28,1] 卷积 [5,5,1,32] -> [-1,24,24,32]->[-1,28,

【tensorflow 全连接神经网络】 minist 手写数字识别

主要内容: 使用tensorflow构建一个三层全连接传统神经网络,作为字符识别的多分类器。通过字符图片预测对应的数字,对mnist数据集进行预测。 # coding: utf-8from tensorflow.examples.tutorials.mnist import input_dataimport tensorflow as tfimport matplotlib.pyplot