Heim > Artikel > Web-Frontend > Verstehen Sie, wie Promise.race() und Promise.any() verwendet werden
Verwandte Empfehlungen: „Javascript-Video-Tutorial“
Seit seiner Veröffentlichung im Jahr 1996 hat sich JS stetig verbessert. Mit vielen Verbesserungen in ECMAScript-Versionen ist die neueste Version ES2020
. Ein wichtiges Update für JS ist Promise, das 2015 unter dem Namen ES6 veröffentlicht wurde. ES2020
。JS 的一个重要更新是Promise,在2015年,它以 ES6 的名义发布。
MDN 上对 Promise 的定义:Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。对于新手来说,这听起来可能有点太复杂了。
国外一位大什么对Promises
的解释如下:“想象一下你是个孩子。 你老妈向你保证,她下周会给你买一部新手机。”
你要到下周才能知道你是否能获取那部手机。你老妈要么真的给你买了一个全新的手机,要么因为不开心就不给你买。
这个就是一个Promise
。 一个Promise
有三个状态。 分别是:
这个是我目前听到,最快能理解 Promise 事例。
如果你还没有开始学习 Promise ,建议你这样做。
Promise包含几种非常有用的内置方法。 今天我们主要介绍这两种方法。
Promise.race()
-与 ES6 一起发布Promise.any()
-仍处于第4阶段的提案中Promise.race()
方法最初是在 ES6 中引入 Promise 时发布的,这个方法需要一个iterable
作为参数。
Promise.race(iterable)
方法返回一个 promise,一旦迭代器中的某个promise
解决或拒绝,返回的 promise 就会解决或拒绝。
与Promise.any()
方法不同,Promise.race()
方法主要关注 Promise 是否已解决,而不管其被解决还是被拒绝。
Promise.race(iterable)
iterable
— 可迭代对象,类似 Array。 iterable 对象实现Symbol.iterator
方法。
一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。
因为参数接受iterable
,所以我们可以传递一些值,比如基本值,甚至数组中的对象。在这种情况下,race
方法将返回传递的第一个非 promise 对象。这主要是因为方法的行为是在值可用时(当 promise 满足时)立即返回值。
此外,如果在iterable
中传递了已经解决的Promise,则Promise.race()
方法将解析为该值的第一个。 如果传递了一个空的Iterable
,则race
方法将永远处于待处理状态。
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'promise 1 resolved'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(reject, 100, 'promise 2 rejected'); }); const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 200, 'promise 3 resolved') }); (async () => { try { let result = await Promise.race([promise1, promise2, promise3]); console.log(result); } catch (err) { console.error(err); } })(); // 输出- "promise 2 rejected" // 尽管promise1和promise3可以解决,但promise2拒绝的速度比它们快。 // 因此Promise.race方法将以promise2拒绝
现在,你可能想知道,我们在实战中何时 Promise.race() ? 来看看。
在请求数据时,显示加载动画
使用加载动画开发中是非常常见。当数据响应时间较长时,如果没使用加载动画,看起来就像没有响应一样。但有时,响应太快了,我们需要加载动画时,增加一个非常小延迟时间,这样会让用户觉得我是在经常请求过来的。要实现这一点,只需使用Promise.race()
方法,如下所示。
function getUserInfo(user) { return new Promise((resolve, reject) => { // had it at 1500 to be more true-to-life, but 900 is better for testing setTimeout(() => resolve("user data!"), Math.floor(900*Math.random())); }); } function showUserInfo(user) { return getUserInfo().then(info => { console.log("user info:", info); return true; }); } function showSpinner() { console.log("please wait...") } function timeout(delay, result) { return new Promise(resolve => { setTimeout(() => resolve(result), delay); }); } Promise.race([showUserInfo(), timeout(300)]).then(displayed => { if (!displayed) showSpinner(); });
取消的 Promise
有些情况下,我们需要取消 Promise,这时也可以借助 Promise.race()
方法:
function timeout(delay) { let cancel; const wait = new Promise(resolve => { const timer = setTimeout(() => resolve(false), delay); cancel = () => { clearTimeout(timer); resolve(true); }; }); wait.cancel = cancel; return wait; } function doWork() { const workFactor = Math.floor(600*Math.random()); const work = timeout(workFactor); const result = work.then(canceled => { if (canceled) console.log('Work canceled'); else console.log('Work done in', workFactor, 'ms'); return !canceled; }); result.cancel = work.cancel; return result; } function attemptWork() { const work = doWork(); return Promise.race([work, timeout(300)]) .then(done => { if (!done) work.cancel(); return (done ? 'Work complete!' : 'I gave up'); }); } attemptWork().then(console.log);
批处理请求,用于长时间执行
Chris Jensen 有一个有趣的race()
方法用例。 他曾使用Promise.race()
方法批处理长时间运行的请求。 这样一来,他们可以保持并行请求的数量固定。
const _ = require('lodash') async function batchRequests(options) { let query = { offset: 0, limit: options.limit }; do { batch = await model.findAll(query); query.offset += options.limit; if (batch.length) { const promise = doLongRequestForBatch(batch).then(() => { // Once complete, pop this promise from our array // so that we know we can add another batch in its place _.remove(promises, p => p === promise); }); promises.push(promise); // Once we hit our concurrency limit, wait for at least one promise to // resolve before continuing to batch off requests if (promises.length >= options.concurrentBatches) { await Promise.race(promises); } } } while (batch.length); // Wait for remaining batches to finish return Promise.all(promises); } batchRequests({ limit: 100, concurrentBatches: 5 });
Promise.any()
接收一个Promise
可迭代对象,只要其中的一个 promise
成功,就返回那个已经成功的 promise
。如果可迭代对象中没有一个 promise
成功(即所有的 promises
都失败/拒绝),就返回一个失败的 promise 和AggregateError
类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()
Promises
wie folgt: „Stellen Sie sich vor, Sie wären ein Kind. Ihre Mutter verspricht Ihnen, dass sie Ihnen nächste Woche ein neues Mobiltelefon kaufen wird. 🎜🎜Sie werden es nicht herausfinden.“ Ich werde bis nächste Woche fragen, ob du das Telefon bekommen kannst. Deine Mutter wird dir entweder tatsächlich ein brandneues Telefon kaufen, oder sie wird es nicht für dich kaufen, weil sie unzufrieden ist. 🎜🎜Dies ist ein Versprechen
. Ein Promise
hat drei Zustände. Sie sind: 🎜Promise.race()
– Veröffentlicht mit ES6 Promise.any()
– Noch in Stufe 4 Im Vorschlag Promise.race()
-Methode wurde ursprünglich veröffentlicht, als Promise in ES6 eingeführt wurde. Diese Methode erfordert einen iterable
als Parameter. Die Methode 🎜🎜Promise.race(iterable)
gibt ein Versprechen zurück, das aufgelöst oder abgelehnt wird, sobald ein promise
im Iterator aufgelöst oder abgelehnt wird. 🎜🎜Im Gegensatz zur Methode Promise.any()
konzentriert sich die Methode Promise.race()
hauptsächlich darauf, ob das Versprechen gelöst wurde, unabhängig davon, ob es gelöst oder abgelehnt wird . 🎜Promise.any(iterable);
iterable
– Iterierbares Objekt, ähnlich wie Array. iterierbare Objekte implementieren die Methode Symbol.iterator
. 🎜iterable
akzeptiert, können wir einige Werte übergeben, z. B. Grundwerte oder sogar Objekte in einem Array. In diesem Fall gibt die Methode race
das erste übergebene Non-Promise-Objekt zurück. Dies liegt hauptsächlich daran, dass das Verhalten der Methode darin besteht, den Wert zurückzugeben, sobald der Wert verfügbar ist (wenn das Versprechen erfüllt ist). 🎜🎜 Wenn außerdem ein aufgelöstes Promise in einem iterable
übergeben wird, löst die Methode Promise.race()
den ersten Wert dieses Werts auf. Wenn ein leeres Iterable
übergeben wird, steht die Methode race
immer an. 🎜const promise1 = new Promise((resolve, reject) => { setTimeout(reject, 100, 'promise 1 rejected'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 400, 'promise 2 resolved at 400 ms'); }); const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 700, 'promise 3 resolved at 800 ms'); }); (async () => { try { let value = await Promise.any([promise1, promise2, promise3]); console.log(value); } catch (error) { console.log(error); } })(); //Output - "promise 2 resolved at 400 ms"
Promise.race()
wie unten gezeigt. 🎜rrreee🎜Cancelled Promise🎜🎜In manchen Fällen müssen wir das Promise stornieren. In diesem Fall können wir auch die Methode Promise.race()
verwenden: 🎜rrreee 🎜Batchverarbeitungsanfragen für lange Ausführung🎜🎜Chris Jensen hat einen interessanten Anwendungsfall für die Methode race()
. Er verwendete die Methode Promise.race()
, um lang laufende Anfragen zu stapeln. Auf diese Weise können sie die Anzahl paralleler Anfragen konstant halten. 🎜rrreeePromise.any()
empfängt ein iterierbares Promise
-Objekt, solange eines der promise
Bei Erfolg wird das erfolgreiche Versprechen
zurückgegeben. Wenn keines der Versprechen
im iterierbaren Objekt erfolgreich ist (d. h. alle Versprechen
schlagen fehl/ablehnen), werden ein fehlgeschlagenes Versprechen und ein AggregateError
-Typ zurückgegeben Instanz von Error, die eine Unterklasse von Error ist und zur Gruppierung einzelner Fehler verwendet wird. Im Wesentlichen ist diese Methode das Gegenteil von Promise.all()
. 🎜注意! Promise.any()
方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)
Promise.any(iterable);
iterable
— 个可迭代的对象, 例如 Array。
Promise
。promise
变成成功(resolve)状态,或者其中的所有的 promises
都失败,那么返回的 promise
就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止,它不会等待其他的 promise 全部完成。
不像 Promise.all()
会返回一组完成值那样(resolved values),我们只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。
同时, 也不像 Promise.race()
总是返回第一个结果值(resolved/reject
)那样,这个方法返回的是第一个 成功的 值。这个方法将会忽略掉所有被拒绝的 promise,直到第一个 promise 成功。
const promise1 = new Promise((resolve, reject) => { setTimeout(reject, 100, 'promise 1 rejected'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 400, 'promise 2 resolved at 400 ms'); }); const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 700, 'promise 3 resolved at 800 ms'); }); (async () => { try { let value = await Promise.any([promise1, promise2, promise3]); console.log(value); } catch (error) { console.log(error); } })(); //Output - "promise 2 resolved at 400 ms"
从上面代码注意到Promise.any()
主要关注解析的值。 它会忽略在100毫秒时拒绝的promise1
,并考虑在400毫秒后解析的promise2
的值。
从最快的服务器检索资源
假设访问我们网站的用户可能来自全球各地。如果我们的服务器基于单个位置,那么响应时间将根据每个用户的位置而不同。但是如果我们有多个服务器,可以使用能够产生最快响应的服务器。在这种情况下,可以使用Promise.any()
方法从最快的服务器接收响应。
原文地址:https://blog.bitsrc.io/introduction-to-promise-race-and-promise-any-with-real-life-examples-9d8d1b9f8ec9
作者:Mahdhi Rezvi
译文地址:https://segmentfault.com/a/1190000038475001
更多编程相关知识,请访问:编程入门!!
Das obige ist der detaillierte Inhalt vonVerstehen Sie, wie Promise.race() und Promise.any() verwendet werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!