関連する推奨事項: 「JavaScript ビデオ チュートリアル 」
JS は 1996 年のリリース以来、着実に改良されてきました。 ECMAScript バージョンには多くの改良が加えられ、最新バージョンは ES2020
です。 JS の重要なアップデートは Promise で、2015 年に ES6 という名前でリリースされました。
MDN の Promise の定義: Promise オブジェクトは、非同期操作の最終的な完了 (または失敗) とその結果値を表すために使用されます。これは初心者にとっては少し複雑すぎるように聞こえるかもしれません。
ある外国人の長老は、約束
について次のように説明しました:「あなたが子供だと想像してください。あなたのお母さんは、来週新しい携帯電話を買ってあげるって約束しています。」
その携帯電話を入手できるかどうかは来週までわかりません。あなたのお母さんは実際にあなたに新しい携帯電話を買ってくれるか、不満を持ってあなたに買ってくれないかのどちらかでしょう。
これは 約束
です。 Promise
には 3 つの状態があります。
- ES6 でリリース
- 提案はまだステージ 4 中
Promise.race()このメソッドは、Promise が ES6 に導入されたときに最初にリリースされました。このメソッドには
iterable# が必要です## をパラメータとして指定します。
メソッドは、イテレータ内の promise
が解決または拒否されると、解決または拒否される Promise を返します。 Promise.any()
Promise.race() メソッドは、Promise が解決されたかどうかに関係なく、主に解決されたかどうかに焦点を当てます。または拒否されました。
Syntax
Promise.race(iterable)
Symbol.iterator メソッドを実装します。
戻り値
非同期的に実行されます。 解決または拒否 (スタックが空になったら)。 Note
パラメータはrace メソッドは、渡された最初の非 Promise オブジェクトを返します。これは主に、メソッドの動作が値が利用可能になると (Promise が満たされたとき) すぐに値を返すためです。
さらに、すでに解決された Promise が
iterable
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()
メソッドを使用します。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.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.any() の 1 つである限り)。 promise 成功した場合は、成功した
promise を返します。反復可能オブジェクト内の
promise がいずれも成功しなかった場合 (つまり、すべての
promises が失敗または拒否された場合)、失敗した Promise とタイプ
AggregateError のインスタンスが返されます。 , これは Error のサブクラスであり、単一のエラーをグループ化するために使用されます。基本的に、このメソッドは
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
更多编程相关知识,请访问:编程入门!!
以上がPromise.race() と Promise.any() の使用方法を理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。