牛刀小试-Promise
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相关推荐
- setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~)
本文很长,列举的情况很多. 在阅读本文之前,如果您有充足的时间,请新建一个项目与本文一同实践. 每段代码都有对应的解释,但是自己动手尝试印象才会更深哦~ setInterval:表示多久执行一次,需要 ...
- C++多线程:异步操作std::async和std::promise
文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...
- ES6中的Promise详解
Promise 在 JavaScript 中很早就有各种的开源实现,ES6 将其纳入了官方标准,提供了原生 api 支持,使用更加便捷. 定义 Promise 是一个对象,它用来标识 JavaScri ...
- 关于ES6中Promise的应用-顺序合并Promise,并将返回结果以数组的形式输出
1.Promise 基础知识梳理 创建一个Promise实例 const promise = new Promise(function(resolve, reject) {if (success){r ...
- promise实现多个请求并行串行执行
早上查资料,偶然发现这个话题,发现自己并不会,于是乎,下来研究了一下. 想想之前我们用jquery写请求的时候,要实现请求的串行执行,我们可能是这么做的. $.ajax({url: '',data: ...
- 异步编程之Promise(2):探究原理
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- 自己动手写cpu pdf_自己动手写 Promise
这段时间在学习Promise,但始终不得要领.为了更好地理解Promise,我决定自己实现一个简易版的Promise,以学习Promise工作原理.该工程名为ToyPromise,仓库地址如下: ht ...
- promise 和 async await区别
什么是Async/Await? async/await是写异步代码的新方式,以前的方法有回调函数和Promise. async/await是基于Promise实现的,它不能用于普通的回调函数. as ...
- Promise - js异步控制神器
微信小程序开发交流qq群 581478349 承接微信小程序开发.扫码加微信. 正文: 首先给来一个简单的demo看看Promise是怎么使用的: <!DOCTYPE html> ...
- Promise的实例用法
设定函数 function chiFan() {return new Promise(function(resolve, reject) {console.log("chiFan" ...
最新文章
- 爬一爬那些年你硬盘存过的“老师”
- 李战:悟透JavaScript 【转】
- Leetcode264. Ugly Number II丑数2
- 【整理】固定资产后续业务处理
- C++ Rand()各种实现
- 高等数学下-赵立军-北京大学出版社-题解-练习10.2
- php property 获取,JavaScript中如何获取和设置property属性代码详解
- linux发送日志命令,linux:记录不同用户使用的命令发送到指定的目录中(可发送到日志服务器中)...
- linux tomcat配置https
- Struts2.0 xml文件的配置(package,namespace,action)
- python编译安装没有c扩展_python – 为什么我在安装simplejson时得到“C扩展无法编译”?...
- Javascript封装
- 详解阿里云第六代增强型实例,性能强劲,百万IOPS加持
- 电工结业试卷_维修电工技师二级难吗考试内容怎么样
- 代码查重实验(深大算法实验4)报告+代码
- 帆软参数设置_帆软报表参数
- 使用.NET Core和Vue搭建WebSocket聊天室
- LayUI项目之我的会议(送审以及排座)
- vue中关于生产evn.production 及开发evn.development 的环境配置说明
- 英语翻译作业(十二)
热门文章
- 用java把word转pdf
- Python 爬虫监控女神的QQ空间新的说说,实现秒赞,并发送说说内容到你的邮箱
- 吴闲云——煮酒探西游
- QQ游戏-大家来找茬 外挂
- 程序员必须了解的10大技术搜索引擎
- 批量图片下载器(整站下载)
- “IT 变革” 云 = 美国道富银行砍掉了850个IT职位
- curl: (6) Could not resolve host: www.huobi.me; Unknown error
- 反垃圾邮件 linux,Linux中Postfix反病毒和垃圾邮件工具(十)
- 17行python代码爬取堆糖网所有MeiNv图片