Promise

// 先定义三个常量表示状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";class MyPromise {constructor(executor) {//executor 是一个执行器,进入会立即执行try {executor(this.resolve, this.reject);} catch (error) {this.reject(error);}}//初始化变量status = PENDING;value = null; //成功reason = null; //失败// 存储成功回调函数onFulfilledCallbacks = [];// 存储失败回调函数onRejectedCallbacks = [];// resolve和reject为什么要用箭头函数?// 如果直接调用的话,普通函数this指向的是window或者undefined// 用箭头函数就可以让this指向当前实例对象// 更改成功后的状态resolve = value => {if (this.status === PENDING) {this.value = value;this.status = FULFILLED;// 判断成功回调是否存在,如果存在就调用while (this.onFulfilledCallbacks.length) {// Array.shift() 取出数组第一个元素,然后()调用,// shift不是纯函数,取出后,数组将失去该元素,直到数组为空this.onFulfilledCallbacks.shift()(value);}}};// 更改失败后的状态reject = reason => {if (this.status === PENDING) {this.reason = reason;this.status = REJECTED;// 判断失败回调是否存在,如果存在就调用while (this.onRejectedCallbacks.length) {this.onRejectedCallbacks.shift()(reason);}}};then(onFulfilled, onRejected) {// 如果不传,就使用默认函数onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;onRejected =typeof onRejected === "function"? onRejected: reason => {throw reason;};// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去const promise2 = new MyPromise((resolve, reject) => {const fulfilledMicrotask = () => {// 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {try {// 获取成功回调函数的执行结果const x = onFulfilled(this.value);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}});};const rejectedMicrotask = () => {// 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {try {// 调用失败回调,并且把原因返回const x = realOnRejected(this.reason);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error);}});};// 判断状态if (this.status === FULFILLED) {fulfilledMicrotask();} else if (this.status === REJECTED) {rejectedMicrotask();} else if (this.status === PENDING) {// 等待// 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来// 等到执行成功失败函数的时候再传递this.onFulfilledCallbacks.push(fulfilledMicrotask);this.onRejectedCallbacks.push(rejectedMicrotask);}});return promise2;}// resolve 静态方法static resolve(parameter) {//如果传入是 MyPromise 就直接返回if (parameter instanceof MyPromise) {return parameter;}//否则返回个 MyPromise 包着它return new MyPromise(resolve => {resolve(parameter);});}// reject 静态方法static reject(reason) {return new MyPromise((resolve, reject) => {reject(reason);});}
}
//解析
function resolvePromise(promise, x, resolve, reject) {if (promise == x) {return reject(new TypeError("Chaining cycle detected for promise #<Promise>"));}//判断 x 是不是 MyPromise 实例对象if (x instanceof MyPromise) {//如果是则表示x为 promise ,//执行 x ,调用 then 方法,目的是将其状态变为 fulfilled或者rejected//x.then(value => resolve(value),reason => reject(reason))x.then(resolve, reject);} else {//普通值resolve(x);}
}/* const promise = new MyPromise((resolve, reject) => {resolve("success");
});// 这个时候将promise定义一个p1,然后返回的时候返回p1这个promise
const p1 = promise.then(value => {console.log(1);console.log("resolve", value);return p1;
});// 运行的时候会走reject
p1.then(value => {console.log(2);console.log("resolve", value);},reason => {console.log(3);console.log(reason.message);}
); */
// promise
//   .then(value => {//     console.log(1);
//     console.log("resolve", value);
//     return other();
//   })
//   .then(value => {//     console.log(2);
//     console.log("resolve", value);
//   });// 第一个then方法中的错误要在第二个then方法中捕获到
/* promise.then(value => {console.log(1);console.log("resolve", value);throw new Error("then error");},reason => {console.log(2);console.log(reason.message);}).then(value => {console.log(3);console.log(value);},reason => {console.log(4);console.log(reason.message);}); */// promise.then().then().then(value => console.log(value))
MyPromise.resolve().then(() => {console.log(0);return MyPromise.resolve(4);}).then(res => {console.log(res);});
  • Promise.all:有 rejected 会直接返回并且只返回这个rejected,否则等全部返回
  • Promise.allSettled(都解决的):全部执行完再返回,返回值里有 status [ “fulfilled” 或 “rejected” ]
  • Promise.race(竞速的):返回第一个执行完的,不论是否 rejected
  • Promise.any:返回第一个成功的,如果全部失败会进 catch
    以上方法参数中有非 promise情况 则按成功状态处理

Promise.all

/*** @description* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功* 如果所有Promise都成功,则返回成功结果数组* 如果有一个Promise失败,则返回这个失败结果* @param* @author lg* @date 2022-02-13 13:40:19*/
function promiseAll(args) {const promises = Array.from(args);const len = promises.length;let count = 0;let resultList = [];//  将三个promise存到一个大的promise中,异步等待执行return new Promise((resolve, reject) => {/*** @param result: promise 结果* @param index: promise 顺序*/function addToResultList(result, index) {count++;resultList[index] = result;if (count === len) {resolve(resultList);}}promises.forEach((promise, index) => {//如果数组里面是都是promise实例if (promise instanceof Promise) {promise.then(result => {addToResultList(result, index);}, reject);} else {//数组中有非Promise实例,此项当做成功;addToResultList(promise, index);}});});
}let pro1 = Promise.resolve(1);
let pro2 = 2;
let pro3 = Promise.resolve(3);promiseAll([pro1, pro2, pro3]).then(data => {console.log("result", data);}).catch(err => {console.log("err", err);});

Promise.allSettled

/*** @description* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功* 把每一个Promise的结果,集合成数组,返回* @param* @author lg* @date 2022-02-13 13:49:59*/function promiseAllSettled(args) {const promises = Array.from(args);const resultList = [];const len = promises.length;let count = 0;return new Promise((resolve, reject) => {if (len === 0) {resolve(resultList);}/*** @param result: promise 结果* @param index: promise 顺序*/function addToResultList(result, index) {count++;resultList[index] = result;if (count === len) {resolve(resultList);}}promises.forEach((promise, index) => {if (promise instanceof Promise) {promise.then(res => {addToResultList({status: "fulfilled",value: res},index);},err => {addToResultList({status: "rejected",reason: err},index);});} else {addToResultList({status: "fulfilled",value: promise},index);}});});
}const p1 = Promise.resolve(1);
const p2 = new Promise(resolve => {setTimeout(() => resolve(2), 1000);
});
const p3 = new Promise(resolve => {setTimeout(() => resolve(3), 3000);
});const p4 = Promise.reject("err4");
const p5 = Promise.reject("err5");
const p11 = promiseAllSettled([p1, p2, p4]).then(res =>console.log(JSON.stringify(res, null, 2))
);

Promise.race

/*** @description* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功* 哪个Promise最快得到结果,就返回那个结果,无论成功失败* @param* @author lg* @date 2022-02-13 13:42:44*/function promiseRace(args) {const promises = Array.from(args); //如果参数不是数组,转成数组return new Promise((resolve, reject) => {promises.forEach(promise => {if (promise instanceof Promise) {//谁先有结果就返回那个结果,无论成功失败promise.then(res => {resolve(res);},err => {reject(err);});} else {resolve(promise);}});});
}
let pro1 = Promise.resolve(1);
let pro2 = 2;
let pro3 = Promise.resolve(3);promiseRace([pro1, pro2, pro3]).then(data => {console.log("result", data);}).catch(err => {console.log("err", err);});

Promise.any

/*** @description* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功* 如果有一个Promise成功,则返回这个成功结果* 如果所有Promise都失败,则报错* @param* @author lg* @date 2022-02-13 17:17:34*/function promiseAny(args) {const promises = Array.from(args);const len = promises.length;let count = 0;return new Promise((resolve, reject) => {if (len === 0) return resolve([]);promises.forEach(promise => {if (promise instanceof Promise) {promise.then(res => {resolve(res);},err => {count++;if (count === len) reject("All promises were rejected");});} else {resolve(promise);}});});
}let pro1 = Promise.reject(1);
let pro2 = Promise.reject(1);
let pro3 = Promise.reject(3);promiseAny([pro1, pro2, pro3]).then(value => {console.log("value: ", value);}).catch(err => {console.log("err: ", err);});

牛刀小试-Promise相关推荐

  1. setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~)

    本文很长,列举的情况很多. 在阅读本文之前,如果您有充足的时间,请新建一个项目与本文一同实践. 每段代码都有对应的解释,但是自己动手尝试印象才会更深哦~ setInterval:表示多久执行一次,需要 ...

  2. C++多线程:异步操作std::async和std::promise

    文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...

  3. ES6中的Promise详解

    Promise 在 JavaScript 中很早就有各种的开源实现,ES6 将其纳入了官方标准,提供了原生 api 支持,使用更加便捷. 定义 Promise 是一个对象,它用来标识 JavaScri ...

  4. 关于ES6中Promise的应用-顺序合并Promise,并将返回结果以数组的形式输出

    1.Promise 基础知识梳理 创建一个Promise实例 const promise = new Promise(function(resolve, reject) {if (success){r ...

  5. promise实现多个请求并行串行执行

    早上查资料,偶然发现这个话题,发现自己并不会,于是乎,下来研究了一下. 想想之前我们用jquery写请求的时候,要实现请求的串行执行,我们可能是这么做的. $.ajax({url: '',data: ...

  6. 异步编程之Promise(2):探究原理

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  7. 自己动手写cpu pdf_自己动手写 Promise

    这段时间在学习Promise,但始终不得要领.为了更好地理解Promise,我决定自己实现一个简易版的Promise,以学习Promise工作原理.该工程名为ToyPromise,仓库地址如下: ht ...

  8. promise 和 async await区别

     什么是Async/Await? async/await是写异步代码的新方式,以前的方法有回调函数和Promise. async/await是基于Promise实现的,它不能用于普通的回调函数. as ...

  9. Promise - js异步控制神器

    微信小程序开发交流qq群   581478349    承接微信小程序开发.扫码加微信. 正文: 首先给来一个简单的demo看看Promise是怎么使用的: <!DOCTYPE html> ...

  10. Promise的实例用法

    设定函数 function chiFan() {return new Promise(function(resolve, reject) {console.log("chiFan" ...

最新文章

  1. 爬一爬那些年你硬盘存过的“老师”
  2. 李战:悟透JavaScript 【转】
  3. Leetcode264. Ugly Number II丑数2
  4. 【整理】固定资产后续业务处理
  5. C++ Rand()各种实现
  6. 高等数学下-赵立军-北京大学出版社-题解-练习10.2
  7. php property 获取,JavaScript中如何获取和设置property属性代码详解
  8. linux发送日志命令,linux:记录不同用户使用的命令发送到指定的目录中(可发送到日志服务器中)...
  9. linux tomcat配置https
  10. Struts2.0 xml文件的配置(package,namespace,action)
  11. python编译安装没有c扩展_python – 为什么我在安装simplejson时得到“C扩展无法编译”?...
  12. Javascript封装
  13. 详解阿里云第六代增强型实例,性能强劲,百万IOPS加持
  14. 电工结业试卷_维修电工技师二级难吗考试内容怎么样
  15. 代码查重实验(深大算法实验4)报告+代码
  16. 帆软参数设置_帆软报表参数
  17. 使用.NET Core和Vue搭建WebSocket聊天室
  18. LayUI项目之我的会议(送审以及排座)
  19. vue中关于生产evn.production 及开发evn.development 的环境配置说明
  20. 英语翻译作业(十二)

热门文章

  1. 用java把word转pdf
  2. Python 爬虫监控女神的QQ空间新的说说,实现秒赞,并发送说说内容到你的邮箱
  3. 吴闲云——煮酒探西游
  4. QQ游戏-大家来找茬 外挂
  5. 程序员必须了解的10大技术搜索引擎
  6. 批量图片下载器(整站下载)
  7. “IT 变革” 云 = 美国道富银行砍掉了850个IT职位
  8. curl: (6) Could not resolve host: www.huobi.me; Unknown error
  9. 反垃圾邮件 linux,Linux中Postfix反病毒和垃圾邮件工具(十)
  10. 17行python代码爬取堆糖网所有MeiNv图片