Promise花落谁家知多少
- 手机
- 2025-08-18 07:48:02

Promise花落谁家知多少 Promise系列导航前言一、Promise.all()1.语法2.代码及说明(1)代码段(2)代码段(3)代码段(4)代码段 二、Promise.any()1.语法2.代码及说明(1)代码段(2)代码段 三、Promise.race()1.语法2.代码及说明(1)代码段(2)代码段(3)代码段(4)代码段(5)代码段 四、Promise.allSettled()1.语法2.代码及说明(1)代码段(2)代码段 总结 Promise系列导航
1.Promise本质击鼓传花的游戏 2.Promise四式击鼓 3.Promise击鼓传花 4.Promise花落谁家知多少
前言 👨💻👨🌾📝记录学习成果,以便温故而知新 Promise系列文章时学习VUE的知识准备,所以就归为VUE系列了。根据MDN的描述,应该是“JavaScript 标准内置对象”,特此说明。Promise系列文章主要是学习MDN中 Promise的心得体会,MDN地址。
先看一下MDN的描述。
Promise.all() MDN的说明:
Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。
Promise.any() MDN的说明:
Promise.any() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个 Promise。当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。
Promise.race() MDN的说明:
Promise.race() 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 Promise。这个返回的 promise 会随着第一个 promise 的敲定而敲定。
Promise.allSettled() MDN的说明:
Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。
MDN说得很明白,四个方法都是静态方法,入参是一个 Promise 可迭代对象,返回是一个单独的 Promise。它们是 promise 并发方法。
本专题叫“花落谁家知多少”,其中“花落谁家”是指Promise对象敲定,进一步是兑现还是拒绝;“知多少”是数量的概念,如所有都兑现,第一个拒绝,第一个对象,任何一个敲定,所有敲定这样的概念。
一、Promise.all() 1.语法Promise.all(iterable)
参数说明:
iterable是 一个可迭代对象,例如 Array 或 String。
返回值:
已兑现(already fulfilled),如果传入的 iterable 为空。异步兑现(asynchronously fulfilled),如果给定的 iterable 中所有的 promise 都已兑现。兑现值是一个数组,其元素顺序与传入的 promise 一致,而非按照兑现的时间顺序排列。如果传入的 iterable 是一个非空但不包含待定的(pending)promise,则返回的 promise 依然是异步兑现,而非同步兑现。异步拒绝(asynchronously rejected),如果给定的 iterable 中的任意 promise 被拒绝。拒绝原因是第一个拒绝的 promise 的拒绝原因。 2.代码及说明硬道理上。
(1)代码段 const p1 = Promise.resolve(1); const p2 = 2; const p3 = new Promise((resolve, reject) => { setTimeout(() => { resolve("魏紫"); }, 100); }); Promise.all([p1, p2, p3]).then((values) => { console.log(values); });运行结果:
MDN说:
Promise.all 等待所有兑现(或第一个拒绝)的结果。
这个说得比较中肯,比之前的长篇大论要简洁明了。
(2)代码段 // 所有的值都不是 Promise,因此返回的 Promise 将被兑现 const p1 = Promise.all([1, 2, 3]); // 输入中唯一的 Promise 已经被兑现,因此返回的 Promise 将被兑现 const p2 = Promise.all([4, 5, 6, Promise.resolve(7)]); // 一个(也是唯一的一个)输入 Promise 被拒绝,因此返回的 Promise 将被拒绝 const p3 = Promise.all([8, 9, 10, Promise.reject(11)]); console.log(p1); console.log(p2); console.log(p3); // 使用 setTimeout,我们可以在队列为空后执行代码 setTimeout(() => { console.log("队列现在为空"); console.log(p1); console.log(p2); console.log(p3); });运行结果:
这段代码终于有了拒绝了。
(3)代码段再回到当初的代码,当初想要获取返回就是考虑到可能会一次获取多张图片。
html2canvas(this.$refs.imgBox, { height: this.$refs.imgBox.scrollHeight, width: this.$refs.imgBox.scrollWidth, }).then((canvas) => { canvas.toDataURL("image/png") });现在再模拟解决一下:
//主调 function test(){ const p1 = Promise.all([getImg(), getImg(), getImg()]); console.log(p1); setTimeout(() => { console.log("队列现在为空"); console.log(p1); }); } function getImg(){ return new Promise((resolve, reject) => { setTimeout(() => { resolve("魏紫") }, 1000); }).then(() => { return "image/png"; }); }运行结果: 感觉高大上了一些……
(4)代码段 const p1 = Promise.all([]); console.log(p1);运行结果: 很无聊地传个空数组,为的只是要看一看运行结果。
二、Promise.any() 1.语法Promise.any(iterable)
参数说明:
一个 promise 的可迭代对象(例如一个数组)。
返回:
已拒绝(already rejected),如果传入的 iterable 为空的话。异步兑现(asynchronously filfilled),当给定的 iterable 中的任何一个 Promise 被兑现时,返回的 Promise 就会被兑现。其兑现值是第一个兑现的 Promise 的兑现值。异步拒绝(asynchronously rejected),当给定的 iterable 中的所有 Promise 都被拒绝时。拒绝原因是一个 AggregateError,其 errors 属性包含一个拒绝原因数组。无论完成顺序如何,这些错误都是按照传入的 Promise 的顺序排序。如果传递的 iterable 是非空的,但不包含待定的 Promise,则返回的 Promise 仍然是异步拒绝的(而不是同步拒绝的)。 2.代码及说明硬道理上。
(1)代码段 const pErr = new Promise((resolve, reject) => { reject("总是失败"); }); const pSlow = new Promise((resolve, reject) => { setTimeout(resolve, 500, "最终完成"); }); const pFast = new Promise((resolve, reject) => { setTimeout(resolve, 100, "很快完成"); }); Promise.any([pErr, pSlow, pFast]).then((value) => { console.log(value); // pFast 第一个兑现 });运行结果: 运行结果正如MDN所说:
Promise.any() 会以第一个兑现的 Promise 来兑现,即使有 Promise 先被拒绝。
(2)代码段 const failure = new Promise((resolve, reject) => { reject("总是失败"); }); Promise.any([failure, Promise.reject("姚黄")]).catch((err) => { console.log(err); });运行结果: 运行结果正如MDN所说:
如果没有 Promise 被兑现,Promise.any() 将使用 AggregateError 进行拒绝。
竟然是以抛异常这种激烈手段拒绝的,貌似没有找到errors属性。
三、Promise.race() 1.语法Promise.race(iterable)
参数说明:
iterable是一个 promise 可迭代对象(例如数组)。
返回值:
一个 Promise,会以 iterable 中第一个敲定的 promise 的状态异步敲定。换句话说,如果第一个敲定的 promise 被兑现,那么返回的 promise 也会被兑现;如果第一个敲定的 promise 被拒绝,那么返回的 promise 也会被拒绝。如果传入的 iterable 为空,返回的 promise 就会一直保持待定状态。如果传入的 iterable 非空但其中没有任何一个 promise 是待定状态,返回的 promise 仍会异步敲定(而不是同步敲定)。
2.代码及说明硬道理上。
(1)代码段 function sleep(time, value, state) { return new Promise((resolve, reject) => { setTimeout(() => { if (state === "兑现") { return resolve(value); } else { return reject(new Error(value)); } }, time); }); } const p1 = sleep(500, "一", "兑现"); const p2 = sleep(100, "二", "兑现"); Promise.race([p1, p2]).then((value) => { console.log(value); // “二” // 两个都会兑现,但 p2 更快 }); const p3 = sleep(100, "三", "兑现"); const p4 = sleep(500, "四", "拒绝"); Promise.race([p3, p4]).then( (value) => { console.log(value); // “三” // p3 更快,所以它兑现 }, (error) => { // 不会被调用 } ); const p5 = sleep(500, "五", "兑现"); const p6 = sleep(100, "六", "拒绝"); Promise.race([p5, p6]).then( (value) => { // 不会被调用 }, (error) => { console.error(error.message); // “六” // p6 更快,所以它拒绝 } );运行结果: 运行结果正如注释所说。
(2)代码段 // 传入一个已经解决的 Promise 数组,以尽快触发 Promise.race。 const resolvedPromisesArray = [Promise.resolve("魏紫1"), Promise.resolve("魏紫2")]; const p = Promise.race(resolvedPromisesArray); // 立即打印 p 的值 console.log(p); // 使用 setTimeout,我们可以在堆栈为空后执行代码 setTimeout(() => { console.log("堆栈现在为空"); console.log(p); });运行结果: 这段代码按MDN所说是看异步性的。
(3)代码段 const foreverPendingPromise = Promise.race([]); console.log(foreverPendingPromise); setTimeout(() => { console.log("堆栈现在为空"); console.log(foreverPendingPromise); });运行结果: 很无聊地传个空数组,只为验证MDN所说:
一个空的可迭代对象会导致返回的 Promise 一直处于待定状态。
(4)代码段 const foreverPendingPromise = Promise.race([]); const alreadyFulfilledProm = Promise.resolve(100); const arr = [foreverPendingPromise, alreadyFulfilledProm, "非 Promise 值"]; const arr2 = [foreverPendingPromise, "非 Promise 值", Promise.resolve(100)]; const p = Promise.race(arr); const p2 = Promise.race(arr2); console.log(p); console.log(p2); setTimeout(() => { console.log("堆栈现在为空"); console.log(p); console.log(p2); });运行结果: 这段代码的各种滋味,自行体味。
(5)代码段 const data = Promise.race([ fetch("/api"), new Promise((resolve, reject) => { // 5 秒后拒绝 setTimeout(() => reject(new Error("请求超时")), 5000); }), ]) .then((res) => res.json()) .catch((err) => displayError(err));这段代码倒是很有借鉴意义。
四、Promise.allSettled() 1.语法Promise.allSettled(iterable)
参数说明:
iterable是一个以 promise 组成的可迭代对象(例如 Array)对象。
返回值:
已兑现(already fulfilled),如果传入的 iterable 为空的话。异步兑现(asynchronously fulfill),当给定的 iterable 中所有 promise 已经敲定时(要么已兑现,要么已拒绝)。兑现的值是一个对象数组,其中的对象按照 iterable 中传递的 promise 的顺序,描述每一个 promise 的结果,无论完成顺序如何。 2.代码及说明硬道理上。
(1)代码段 Promise.allSettled([ Promise.resolve(33), new Promise((resolve) => setTimeout(() => resolve(66), 0)), 99, Promise.reject(new Error("一个错误")), ]).then((values) => console.log(values));运行结果: 运行结果正如MDN所说:
每个结果对象都有以下的属性:
status:一个字符串,要么是 “fulfilled”,要么是 “rejected”,表示 promise 的最终状态。 value:仅当 status 为 “fulfilled”,才存在。promise 兑现的值。 reason:仅当 status 为 “rejected”,才存在,promsie 拒绝的原因。
(2)代码段 const p = Promise.allSettled([]); console.log(p); setTimeout(() => { console.log("堆栈现在为空"); console.log(p); });运行结果: 把无聊进行到底也是一种境界。
总结到此整个Promise系列就结束了,现在给整个系列做个总结:四击、三传与四知。
Promise花落谁家知多少由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Promise花落谁家知多少”