[解決済み] Node JSのPromise.allとforEach
2022-04-29 09:19:34
質問
私は、非同期メソッドを公開する配列のような構造体を持っています。非同期メソッド呼び出しは、順番に、より多くの非同期メソッドを公開する配列構造を返します。私はこの構造から得られた値を格納するために別のJSONオブジェクトを作成しているので、私はコールバックで参照を追跡することに注意する必要があります。
私はブルートフォースソリューションをコーディングしましたが、よりイディオムまたはクリーンなソリューションを学びたいと思います。
- パターンは、nレベルの入れ子に対して反復可能であるべきである。
- promise.allかそれに類するテクニックを使って、いつ囲むルーチンを解決するかを決める必要があります。
- すべての要素が必ずしも非同期呼び出しに関係するとは限りません。そのため、ネストされたpromise.allでは、インデックスに基づいてJSON配列の要素に単純に代入することはできないのです。それでも、ネストされたforEachでpromise.allのようなものを使って、内包するルーチンを解決する前に、すべてのプロパティの割り当てが行われたことを確認する必要があるのです。
- 私はbluebird promise libを使用していますが、これは必須条件ではありません。
以下はコードの一部です。
var jsonItems = [];
items.forEach(function(item){
var jsonItem = {};
jsonItem.name = item.name;
item.getThings().then(function(things){
// or Promise.all(allItemGetThingCalls, function(things){
things.forEach(function(thing, index){
jsonItems[index].thingName = thing.name;
if(thing.type === 'file'){
thing.getFile().then(function(file){ //or promise.all?
jsonItems[index].filesize = file.getSize();
解決方法は?
簡単なルールがあるので、とてもわかりやすいですね。
-
でプロミスを作成すると、必ず
then
を返します。 - を返さないプロミスは、外で待たされることはないでしょう。 -
複数のプロミスを作成した場合
.all
それら - そうすれば、すべてのプロミスを待ち、どれからのエラーも黙殺されることはありません。 -
ネストするたびに
then
の場合、通常、途中で戻ることができます。 -then
チェーンは通常、せいぜい1レベルまでの深さしかありません。 - IOを実行するときは、必ずプロミスで行うこと - プロミスの中に入れるか、プロミスを使用して完了を知らせるか、どちらかでなければなりません。
そして、いくつかのヒント。
-
マッピングは
.map
よりもfor/push
- 関数で値をマッピングしている場合。map
を使うと、アクションをひとつずつ適用して結果を集約するという概念を簡潔に表現することができます。 -
同時実行は自由であれば、順次実行よりも優れている
- 同時並行で実行し、待つ方が良いのです
Promise.all
次から次へと実行し、それぞれが次の実行の前に待機するよりも。
OK、では早速始めましょう。
var items = [1, 2, 3, 4, 5];
var fn = function asyncMultiplyBy2(v){ // sample async action
return new Promise(resolve => setTimeout(() => resolve(v * 2), 100));
};
// map over forEach since it returns
var actions = items.map(fn); // run the function over all items
// we now have a promises array and we want to wait for it
var results = Promise.all(actions); // pass array of promises
results.then(data => // or just .then(console.log)
console.log(data) // [2, 4, 6, 8, 10]
);
// we can nest this of course, as I said, `then` chains:
var res2 = Promise.all([1, 2, 3, 4, 5].map(fn)).then(
data => Promise.all(data.map(fn))
).then(function(data){
// the next `then` is executed after the promise has returned from the previous
// `then` fulfilled, in this case it's an aggregate promise because of
// the `.all`
return Promise.all(data.map(fn));
}).then(function(data){
// just for good measure
return Promise.all(data.map(fn));
});
// now to get the results:
res2.then(function(data){
console.log(data); // [16, 32, 48, 64, 80]
});
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] package.jsonのチルダ(~)とキャレット(^)の違いは何ですか?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] npm package.jsonファイルのdependencies, devDependencies, peerDependenciesの違いは何ですか?
-
[解決済み] forEachループでasync/awaitを使用する
-
[解決済み] Node.jsを完全にアンインストールして、最初から再インストールする方法 (Mac OS X)
-
[解決済み] Node.jsのmodule.exportsの目的と使い方を教えてください。
-
[解決済み】PromiseとObservablesの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JSクロスドメインソリューション リアクト構成 リバースプロキシ
-
親子コンポーネント通信を解決する3つのVueスロット
-
vueのグローバルがscss(mixin)を導入。
-
[解決済み】Node Version Manager のインストール - nvm コマンドが見つかりません。
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
[解決済み】リクエストに失敗していないのに、「TypeError: failed to fetch」が表示される。
-
[解決済み】ReactJSでエラー発生 Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。