質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2161閲覧

javascriptのPromise.allでの並列処理について

shimotani1028

総合スコア5

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/12/17 04:50

javascriptで並列処理がしたくPromiseについて勉強しています。
ある重たい処理を並列処理したく、以下のようなコードを作成しました。
作成した10個のPromiseオブジェクトをPromise.allで並列処理したかったのですが、
出力結果を見る限り、
Promiseオブジェクトを作成した時点(promise.push(test(i))の部分)で、
test1()のconsole.logが実行されているみたいでこれが理解できません。
Promise.allを実行して初めて並列処理が行われるものだと思っていたのですが、
これでは並列処理の前にもうすでにすべてのtest1()が実行されており、並列処理の意味がないように思っています。
どのようにすればPromise.allで並列処理が実行できるのでしょうか。教えていただければ幸いです。

javascript

1// 重たい処理の代わり 2function test1(i){ 3 return new Promise((resolve) => { 4 console.log(i) 5 resolve(i+"OK"); 6 }); 7} 8 9var promise = []; 10for (let i=0; i<10; i++){ 11 promise.push(test1(i)); 12} 13console.log('並列処理スタート') 14 15Promise.all(promise) 16 .then((str1) => { 17 console.log(str1); 18 }) 19 .catch((str1) => { 20 console.log("NG"); 21 });

consolelog

10 21 32 43 54 65 76 87 98 109 11並列処理スタート 12[ 13 '0OK', '1OK', '2OK', 14 '3OK', '4OK', '5OK', 15 '6OK', '7OK', '8OK', 16 '9OK' 17]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

並列で実行はされます。
Promise.allは並列の最後の処理を待って結果をまとめて表示するだけです

javascript

1const test1=async(i)=>new Promise(resolve=>{ 2 setTimeout(()=>{ 3 console.log(i); 4 resolve(i+"OK"); 5 },5000-500*i); 6}); 7var p = []; 8for (let i=0; i<10; i++){ 9 p.push(test1(i)); 10} 11console.log('並列処理スタート'); 12Promise.all(p).then(str1=>{ 13 console.log(str1); 14});

投稿2021/12/17 05:30

yambejp

総合スコア114769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shimotani1028

2021/12/17 05:41

回答ありがとうございます。 new PromiseでsetTimeoutされていますが、 ここで時間を待った方が同期的に実行するよりはやいのでしょうか。
guest

0

ベストアンサー

Promiseオブジェクトを作成した時点(promise.push(test(i))の部分)で、

test1()のconsole.logが実行されているみたいでこれが理解できません。

new Promiseの引数になった関数は、同期的に実行されます。

投稿2021/12/17 04:54

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shimotani1028

2021/12/17 05:02

初心者であまりわかっていないのですが、 それでは同期的に実行とは、どの部分での処理の話でしょうか。
maisumakun

2021/12/17 05:02

> どのようにすればPromise.allで並列処理が実行できるのでしょうか。 タイマー、通信など、何かしらの非同期で動く動作を組み込む必要があります。ブラウザJavaScriptは(Workerを作成しない限り)シングルスレッドであり、同期的動作の並列実行は不可能です。
maisumakun

2021/12/17 05:04

> 同期的に実行とは、どの部分での処理の話でしょうか。 test1関数を呼んだ際に、new Promiseの内側の関数を実行してから、その結果のPromiseが返されます。
maisumakun

2021/12/17 05:09

> Promise.allを実行して初めて並列処理が行われるものだと思っていたのですが、 (非同期処理であっても)そんなことはありません。Promiseは作成された瞬間から処理がスタートしています。
shimotani1028

2021/12/17 05:09

ありがとうございます。ネット記事でPromise.allは並列実行できると書いてありますが、 並列実行しているように見えているだけなんですね。 new Promiseの内側の関数を実行してからPromiseが返されるということは、 その後のPromise.allはなんの意味があるのでしょうか。
maisumakun

2021/12/17 05:14

> ネット記事でPromise.allは並列実行できると書いてありますが、 並列実行しているように見えているだけなんですね。 いえ、Promise.allなしでも、複数のPromiseは(非同期動作なら)並列に実行されます。Promise.allは、その「全部が終わったタイミング」を知ることができる、という関数なのです。 今回は、Promise自体が非同期動作を行わないので、あまり意味のないコードとなっています。
shimotani1028

2021/12/17 05:21

ここでいう並列実行=非同期ということですね。 では上記の例ではPromise.allの前にもう並列処理が行われているということなんですかね。 試しにforループのi=10000として実行してみたのですが、 console.log('並列処理スタート')が実行されるのはforループがすべて終わってからだったのですが、 これはどういうことでしょうか。 たびたび申し訳ございません。
maisumakun

2021/12/17 05:23

今回のコードは、Promise.all().thenの中身を除けば、非同期処理に「なっていません」。大量のPromiseを生成する処理は、同期的に実行されています。
maisumakun

2021/12/17 05:25

> 上記の例ではPromise.allの前にもう並列処理が行われているということなんですかね。 いえ、全部のPromiseを生成して、console.log('並列処理スタート')の行を実行するまで、同期的な処理です。
shimotani1028

2021/12/17 05:29

ご回答ありがとうございます。 それでは上記の例でいう、大量のPromise作成部分を非同期実行したいのですが、 その場合はどのような方法があるか教えていただけますでしょうか。
maisumakun

2021/12/17 05:31

> それでは上記の例でいう、大量のPromise作成部分を非同期実行したいのですが ブラウザJavaScriptでは不可能です(非同期処理に入るとしても、最初のPromise生成処理は同期的に行う他ありません)。
maisumakun

2021/12/17 05:36

例としてでなく、本当にしたい「時間のかかる処理」はどのようなものなのでしょうか?
shimotani1028

2021/12/17 05:39

物理演算です。物体が大量にあってその動きを一つ一つ計算したいのですが、 物体同士は干渉しないものなので、並列で計算できれば計算時間が短縮できると思った次第です。
maisumakun

2021/12/17 05:41

でしたら、Workerを利用する必要があります。
shimotani1028

2021/12/17 05:44

Workerというものがあるのですね。ありがとうございます。勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問