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

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

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

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

Q&A

解決済

4回答

1230閲覧

JavaScriptで、処理内容の多い関数の出力が最後になるようにしたい(各関数を非同期で動作するようにしたい)

tada_tadaa

総合スコア112

JavaScript

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

2グッド

4クリップ

投稿2024/10/01 01:21

実現したいこと

プログラムを実行すると

func1()が実行されました。 func2()が実行されました。i = 100000000 func3()が実行されました。

となります。func2()関数は処理内容が多いので、遅れて出力されるようにしたいです。
つまり、各関数が同期的に順番に実行されるのではなく、非同期的に、処理が早く終わった関数から出力されるようにしたいです。

発生している問題・分からないこと

それぞれの関数を非同期にして、早く終わった関数から出力されるような非同期処理の実装方法が分からない。

該当のソースコード

javascript

1 2var func1 = async function(){ 3 console.log("func1()が実行されました。"); 4}; 5 6var func2 = async function(){ 7 for(var i = 0, j = 0; i < 100000000; i++){ 8 j = i; 9 } 10 return new Promise((resolve) => { 11 console.log("func2()が実行されました。i = " + i); 12 resolve(); 13 }); 14}; 15 16var func3 = async function(){ 17 console.log("func3()が実行されました。"); 18}; 19 20(async () => { 21 await func1(); // func1を待つ 22 await func2(); // func2を待つ 23 await func3(); // func3を待つ 24})(); 25 26

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

awaitを消したり、asyncを消したり試したが、ダメだった。

補足

特になし

juner, masa_uchi👍を押しています

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

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

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

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

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

Lhankor_Mhy

2024/10/01 07:27

JavaScript の async/await は並列処理ではなくて、キューだということをご理解された方がいいと思います。 イベントやタイマーなども一見は割り込み処理のように見えますが、実態はキューです。 https://qiita.com/sho_U/items/f07a4f3e7760a9729f10
guest

回答4

0

それぞれの関数を非同期にして、早く終わった関数から出力される

という仕様ならawaitをやめればいいだけでは?

javascript

1const func1=()=>new Promise(resolve=>setTimeout(()=>(console.log(1),resolve()),100)); 2const func2=()=>new Promise(resolve=>setTimeout(()=>(console.log(2),resolve()),1000)); 3const func3=()=>new Promise(resolve=>setTimeout(()=>(console.log(3),resolve()),200)); 4func1(); 5func2(); 6func3();

※ちなみに負荷の高い処理は命題で言う大量のループ処理はそのまま回すのではなくwokerで処理をするのが懸命です

参考

workerでの処理

javascript

1<script id="myWorker" type="javascript/worker"> 2const func=(n)=>{ 3 const t=new Date().getTime(); 4 const wait=300; 5 while(new Date().getTime()<t+wait){ 6 void(0); 7 } 8 return n; 9}; 10self.addEventListener('message',e=>{ 11 self.postMessage(func(e.data)); 12}); 13</script> 14<script> 15const blob = new Blob([document.querySelector('#myWorker').textContent]); 16const worker = new Worker(window.URL.createObjectURL(blob)); 17worker.onmessage=e=>{ 18 console.log(e.data); 19} 20const func1=()=>new Promise(resolve=>setTimeout(()=>(console.log(1),resolve()),200)); 21const func2=()=>worker.postMessage(2); 22const func3=()=>new Promise(resolve=>setTimeout(()=>(console.log(3),resolve()),100)); 23func1(); 24func2(); 25func3(); 26</script>

投稿2024/10/01 02:10

編集2024/10/01 05:27
yambejp

総合スコア116250

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

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

juner

2024/10/01 05:02 編集

元のコードの `j = i;` のあとに `await Promise.resolve()` でも入れて、エントリーポイントを待たなければよさげですね
guest

0

async functionはそれだけで非同期関数です。
awaitを消せば実行を待たず(同期せず)処理されているはずです。

ほかの回答でPromise.allに触れている人がいますが、Promiseは関数の実行順序を制御するためのクラスで、質問とは関係がないので恐らく混乱します。

ちなみに、誤解されていると思いますが、setTimeoutは非同期処理をテストするためによく使われるもので、実際の重い処理をシュミレートするために使っていると思われます。

setTimeoutを使って「同期的」に処理されているのであれば質問通り不具合が出ていて、「非同期的」に処理されているのであれば質問内容は解決しています。

※質問文に記載のあるコードは明らかにおかしいですが、promiseは今回不要であるため言及しません。

追記1

あとから出しゃばっておきながら、
JavaScriptがシングルスレッドだということを完全に漏らしていました。
他回答者さんの言う通り任意の処理を別スレッドで行いたい場合、wokerを使用するのが正しい解決方法になります。

文章がごちゃつきそうなので、元の回答はあえてそのままにしますが、要望があれば修正しますり

投稿2024/10/01 04:41

編集2024/10/01 07:41
utm.

総合スコア220

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

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

juner

2024/10/01 04:59 編集

async function 自体は 中で await されるまでは 同期的に実行されるので どこかで `await Promise.resolve()` でも挟めば非同期(キューを後に送ってくれる状態)になりますね。( thenable を await することで Promise.prototype.then() に相当する挙動をする為
utm.

2024/10/01 05:51

ちょっと何言ってるか分からない
juner

2024/10/01 06:31

次のコードは 1 2 3 4 5 6 の順番に実行されるってことです。 ```js console.log('1'); (async function() { console.log('2'); await Promise.resolve(); console.log('4'); })(); Promise.resolve() .then(() => console.log('5')); queueMicrotask(() => console.log('6')); console.log('3'); ```
utm.

2024/10/01 07:38

なるほど。JavaScriptがシングルスレッドであることを言いたかったのですね。 確かにそんな仕様がありました。忘れていました。 今回の例で言うと、先の回答者さんのあげている通りwokerを使用するのが適当という話になりますね。 回答に補足します。
guest

0

ベストアンサー

非同期メソッドに於ける非同期範囲についての誤解がある様なので そのコードでは次の問題があります。

  • Promise のコンストラクタ自体は同期的に実行される
  • async function は await が入るまでは同期的に実行される
  • await するとその完了を待ってしまう為他の await が実行されることはない

その為、func2 は次の様にすればあとに実行されます。
(※ await Promise.resolve()setTimeout() ではなく queueMicrotask() なので 最小限の非同期となります(他の同期が優先されるだけならこれでよい

js

1var func2 = async function(){ 2 await Promise.resolve(); 3 for(var i = 0, j = 0; i < 100000000; i++){ 4 j = i; 5 } 6 console.log("func2()が実行されました。i = " + i); 7};

ただ、このままでは順番に実行されてしまうので並行実行する為に エントリーポイントを次の様に修正します

js

1(async () => { 2 await Promise.all([ 3 func1(), // func1を待つ 4 func2(), // func2を待つ 5 func3(), // func3を待つ 6 ]); 7})();

以上の修正でうまくいくと思われます。

参考:

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

https://developer.mozilla.org/ja/docs/Web/API/Window/queueMicrotask

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

追伸:

もしもそれぞれの func の先頭に await Promise.resolve() するのであれば func2 は次の様にした方がいいかもしれません。

js

1var func2 = async function(){ 2 await Promise.resolve(); 3 for(var i = 0, j = 0; i < 100000000; i++){ 4 j = i; 5 await Promise.resolve(); 6 } 7 console.log("func2()が実行されました。i = " + i); 8};

追伸2:

javascript のメインスレッドは シングルスレッドです。この方法は await でキューに分けることで 処理を分割して並行で動作している様に見える方法なので
もしも 完全並行処理を行いたいのであればウェブワーカー API をお試しください

https://developer.mozilla.org/ja/docs/Web/API/Worker

追伸3:

ウェブワーカーAPIを使ったコードも書いておきます。

js

1var func1 = async function () { 2 console.log("func1()が実行されました。"); 3}; 4 5var func2 = async function () { 6 const source = ` 7globalThis.addEventListener('message', ({data}) => { 8 for(var i = 0, j = 0; i < data; i++){ 9 j = i; 10 } 11 globalThis.postMessage(i); 12}) 13`; 14 15 const url = `data:text/javascript;base64,${btoa(source)}`; 16 const {promise, resolve, reject} = Promise.withResolvers(); 17 const worker = new Worker(url); 18 worker.addEventListener('error', reject); 19 worker.addEventListener('messageerror', reject); 20 worker.addEventListener('message', ({data}) => resolve(data)); 21 worker.postMessage(100000000); 22 const i = await promise; 23 return new Promise((resolve) => { 24 console.log("func2()が実行されました。i = " + i); 25 resolve(); 26 }); 27}; 28 29var func3 = async function () { 30 console.log("func3()が実行されました。"); 31}; 32(async () => { 33 await Promise.all([ 34 func1(), // func1を待つ 35 func2(), // func2を待つ 36 func3(), // func3を待つ 37 ]); 38})();

playground

投稿2024/10/01 02:20

編集2024/10/02 00:47
juner

総合スコア274

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

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

utm.

2024/10/01 04:50

Promise.allはプロミスを返します。制御しないのであれば無意味です
juner

2024/10/01 05:00

元の await するニュアンスに合わせると Promise.all([]) を await した形でいいのでは?感あります。 事後処理が無かったにしても。
utm.

2024/10/01 05:46

確かにそのようにも読解可能ですね笑
tada_tadaa

2024/10/01 06:03

3種類のパターンを試してみました。 /****************①ここから ******************/ var func1 = async function () { for(var i = 0, j = 0; i < 1000000000; i++){ j = i; } await Promise.resolve(); console.log("func1()の処理が終わりました"); }; var func2 = async function () { for(var i = 0, j = 0; i < 100000000; i++){ j = i; } await Promise.resolve(); console.log("func2()の処理が終わりました"); }; var func3 = async function () { for(var i = 0, j = 0; i < 1000000; i++){ j = i; } await Promise.resolve(); console.log("func3()の処理が終わりました"); }; (async () => { await Promise.all([ func1(), // func1を待つ func2(), // func2を待つ func3(), // func3を待つ ]); })(); /* 出力結果 func1()の処理が終わりました func2()の処理が終わりました func3()の処理が終わりました */ await Promise.resolve();を各関数に記述して試したら同期的に出力された。望んでいるのはawait Promise.resolve();を記述した関数だけが遅れて出力されるのではなく、処理が多い関数が遅れて出力されるのを希望している。 /****************①ここまで ******************/ /****************②ここから ******************/ var func1 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>resolve(), 3000); }) }; var func2 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>resolve(), 1000); }) }; var func3 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>resolve(), 100); }) }; (async () => { func1().then(()=>{console.log("1が終了")}); func2().then(()=>{console.log("2が終了")}); func3().then(()=>{console.log("3が終了")}); })(); /* 出力結果 3が終了 2が終了 1が終了 */ //setTimeoutは別のスレッドで実行されるみたいな事を読んだ気がするので、うまく非同期で(処理が多い関数が遅れて出力される)実行されるのだろうか? /****************②ここまで ******************/ /****************③ここから ******************/ var func1 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>{ for(var i = 0, j = 0; i < 1000000000; i++){ j = i; } resolve(i); },10); }); }; var func2 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>{ for(var i = 0, j = 0; i < 10000000; i++){ j = i; } resolve(i); },10); }); }; var func3 = async function () { return new Promise((resolve, reject)=>{ setTimeout(()=>{ for(var i = 0, j = 0; i < 100000; i++){ j = i; } resolve(i); },10); }); }; (async () => { func1().then(()=>{console.log("1が終了。")}); func2().then(()=>{console.log("2が終了。")}); func3().then(()=>{console.log("3が終了。")}); })(); /* 出力結果 1が終了。 2が終了。 3が終了。 */ //②でsetTimeoutを用いたらうまく非同期で処理されたので、settimeout関数内に処理を書いたら、うまく非同期になるのかと思ったが、同期的(記述順)に出力された。 /****************③ここまで ****************** juner様が教えてくれた await Promise.resolve() を①のパターンで試してみたのですが、同期的に出力されました。やり方がおかしいのでしょうか?
juner

2024/10/01 06:23

Promise を await すること ……つまり then() することは 以降の処理を queueMicrotask で後のタスクに追加するので `j = i` の後あたりに `await Promise.resolve()` すれば 回数多い方が最後になるのではないでしょうか?
tada_tadaa

2024/10/01 06:55

juner様の追記された方法を試してみました。 /****************⑥ここから ******************/ var func1 = async function () { await Promise.resolve(); for(var i = 0, j = 0; i < 100000000; i++){ j = i; await Promise.resolve(); } console.log("func1()の処理が終わりました"); }; var func2 = async function () { await Promise.resolve(); for(var i = 0, j = 0; i < 1000000; i++){ j = i; await Promise.resolve(); } console.log("func2()の処理が終わりました"); }; var func3 = async function () { await Promise.resolve(); for(var i = 0, j = 0; i < 10000; i++){ j = i; await Promise.resolve(); } console.log("func3()の処理が終わりました"); }; (async () => { await Promise.all([ func1(), // func1を待つ func2(), // func2を待つ func3(), // func3を待つ ]); })(); /* 出力結果 func3()の処理が終わりました func2()の処理が終わりました func1()の処理が終わりました */ /****************⑥ここまで ******************/ うまく非同期で出力されました。しかしより多くの複雑な処理を行う関数の場合に、処理の一つ一つにawait Promise.resolve();を記述していくのは大変です。もっと簡単な方法ないでしょうか?例えば j=i;の下にawait Promise.resolve();を記述しましたが、それをコメントアウトすると、また同期的に出力されます。その同期的に出力されるときに、func1の処理がしている間、func2とfunc3の出力はされません。と、いう事は、for文の上に記述したawait Promise.resolve();だけでは、非同期は実現できないという事です。j=i;の下にawait Promise.resolve();を書かないといけないのであれば、他のより多くの処理を行う複雑な関数であれば、一つ一つの処理文に、await Promise.resolve();を書かないといけないということになるような気がします。
juner

2024/10/01 07:12 編集

javascript の メインスレッドは シングルタスクなので そこに 分割したキューを流し込んでいる感じなので await Promise.resolve() で 現在の処理をキューに分割して積んでいる形となります。 一つの長い処理をそのまま実行してもそれは 他を押しのけて実行されるのでそれが実行されている間は他は動作しないです。 あと、 async function は 上記の通り 最初に await するまでは同期で、 await するとそこから awiat までがキューに分割される様なものなので、適当なタイミングで await Promise.resolve() することで 並行動作っぽく処理することができます。 もしも 完全並行処理を行いたいのであればウェブワーカー API をお試しください https://developer.mozilla.org/ja/docs/Web/API/Worker
utm.

2024/10/01 07:55

うまく非同期で処理されているように見えるのは単にループの数(というか、 await Promise.resolve();が呼ばれる数)が異なるからですけど、それで良いのでしょうか...? await Promise.resolve();で処理を中断するのもナンセンスに見えるのですが。 Promise.resolveでなくてもなんのAPIでもいいことになりますが。
juner

2024/10/01 08:48

Promise.resolve() をしたいのではなくて キューに分割したいなので( 敢えて言うなら .then() したいだけ queueMicrotask で後に回したいだけ( setTimeout() だと UIまで巻き込むので時間がかかる為
utm.

2024/10/01 09:42

はい。なので後に回したいなら、極論なんでもいいということになります(そう言ってます)。 そういった、ミスマッチなテクニックのための処理に関して あなたはそれが適切な解決策だと考えているのでしょうか?分かり合えませんね。 アンチパターンにしか思えませんし、断りもなく推奨するのはあまり好ましくないように私は考えるまでです。
juner

2024/10/01 21:12

ただし、 queueMicotask をするだけの為のできるだけコストの低いもののアプローチとなると Promise.resolve くらいしかないのが実状ではあります。
tada_tadaa

2024/10/03 22:17

Lhankor_Mhy様が教えてくれた https://qiita.com/sho_U/items/f07a4f3e7760a9729f10 でpromiseでの非同期な処理と言われるものの詳細を知ることができました。 本で読んだpromisの説明の中で非同期の図が描かれており、A,B,Cの処理があり、同期だとA→B→Cの順に処理するが非同期だとBが処理している間にCを処理する、みたいな説明で、僕はてっきりpromiseやasyncなどでそれが実現できるように勘違いしました。 さらにpromiseの利用例としてsetTimeoutが早く終わった順にpromiseのthenメソッドで続きの処理を実行している事から、setTimeoutの部分を別の処理に置き換えれば、同じように早く終わった処理から、thenメソッドで続きの処理を続行できるように勘違いしていました。 正確ではないと思いますが僕なりの理解では、A、B、Cの処理を同時に実行し、早く終わったものから順に出力するというような事はpromiseやasyncでは実現できない。A,B,Cの処理を同時に実行するというのは並列処理であり、promiseやasyncにはそのような機能はない。javascriptはコールスタックというスタックに、処理する予定のモノ(関数とか)をどんどん積んでいきつつ処理していく。 https://www.jsv9000.app/ で、javascriptのプログラムでのコールスタック、タスクキュー、マイクロタスクキューに処理が追加されていく様子を目で見て確認できるので、より理解を深める事ができました。 コールスタックには関数単位で処理が積み重ねられていき、ある関数の処理をしているときに、同時に別の関数を処理するような並列処理の機能はない。(つまりjavascriptはシングルスレッド) promiseの説明でよく用いられるsetTimeoutは早く時間が来た順に、setTimeoutの第一引数内の処理をスタックに追加していってるだけなので、スタックに積まれた順にsetTimeouの第一引数の処理を順番にこなしている。だからA,B,Cの処理で先に終了したものを出力するような事はできず、スタックに積まれた順に一つづつ処理していく事しかできない。 そして、例えば 複数のfetch()でURLを指定して、そのページのhtml文字列を取得するような場合、早くhtml文字列を取得できたものから順に次の処理に進むような場合、これは完全に非同期的な動きでありますが、このfetch()自体は、内部でワーカーを起動して、並列処理にしているようなので、それで非同期的な動作を実現しているようです。 だから、promiseやawaitで非同期(並列処理と言うべきか?)を実現できるわけではなく、処理が終わった事を知らせて次の処理に進めるような働きしかないと理解しました。
tada_tadaa

2024/10/03 22:19

回答ありがとうございます。 試したところ問題が解決しました! ベストアンサーに選ばせていただきました。
guest

0

基本的には Promise.all([func1(), func2(), func3()]); でいいものですが、質問文の例だと func2() 実行中は他の処理がブロックされるので、質問文の例そのものでは期待通りに動かすことは不可能です。

func2()をたとえば以下のように変更すると試すことができるかと思います。

js

1const func2 = () => { 2 return new Promise(resolve => setTimeout(() => { 3 console.log("func2()が実行されました。"); 4 resolve(); 5 }, 5000)); 6};

func1() func2() func3() の本来の処理内容に非同期なものが一切ない場合、それらを同時に処理を進めるには複数のスレッドが必要になります。ウェブワーカーを使うことになります。

具体的な処理内容がわかれば、また別の方法もあるかもしれません。

投稿2024/10/01 01:30

編集2024/10/01 04:53
int32_t

総合スコア21559

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

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

tada_tadaa

2024/10/01 02:06

以下のように実行部分をコメントアウトして新しくPromise.allで試しました。 //(async () => { // await func1(); // func1を待つ // await func2(); // func2を待つ // await func3(); // func3を待つ //})(); Promise.all([func1(), func2(), func3()]); しかしこれでもfunc2が最後に出力されるような事はなく、func1,func2,func3の順に出力されてます。 それから int32_t様のsetTimeoutを使って出力されるのを遅くしている回答ですが、単純に処理内容が多い関数が、遅れてconsole.log()が出力されるようにしたいのです。setTimeoutを使って、出力のタイミングをずらすのは求めている回答ではないです。
int32_t

2024/10/01 02:10

func2()の本来の処理内容に非同期なものがなく単純に重い処理なら、このアプローチでの解決は無理です。必要なのは非同期処理ではなく並列処理なので、ウェブワーカーが必要になります。
juner

2024/10/01 05:02 編集

async function は await が入るまでは同期なので `await Promise.resolve()` を入れてやればいいのではないでしょうか? 具体的には `j = i;` の後あたりに
tada_tadaa

2024/10/01 06:18

func2()の処理内容に非同期なものがあればよいのでしょうか?具体的にどのように非同期なものを含めればよいのでしょうか?自分なりに以下の2パターンを試してみましたがうまく非同期になりませんでした。 /****************④ここから ******************/ var func1 = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 100000000; i++){ j = i; } resolve(); console.log("func1()の処理が終わりました"); }) }; var func2 = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 1000000; i++){ j = i; } resolve(); console.log("func2()の処理が終わりました"); }) }; var func3 = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 10000; i++){ j = i; } resolve(); console.log("func3()の処理が終わりました"); }) }; (async () => { await Promise.all([ func1(), // func1を待つ func2(), // func2を待つ func3(), // func3を待つ ]); })(); /* 出力結果 func1()の処理が終わりました func2()の処理が終わりました func3()の処理が終わりました */ /****************④ここまで ******************/ /****************⑤ここから ******************/ var func1b = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 1000000000; i++){ j = i; } resolve(); }) } var func2b = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 100000; i++){ j = i; } resolve(); }) } var func3b = async function () { new Promise((resolve, reject) => { for(var i = 0, j = 0; i < 10000; i++){ j = i; } resolve(); }) } var func1 = async function () { await func1b(); console.log("func1()の処理が終わりました"); }; var func2 = async function () { await func2b(); console.log("func2()の処理が終わりました"); }; var func3 = async function () { await func3b(); console.log("func3()の処理が終わりました"); }; (async () => { await Promise.all([ func1(), // func1を待つ func2(), // func2を待つ func3(), // func3を待つ ]); })(); /* 出力結果 func1()の処理が終わりました func2()の処理が終わりました func3()の処理が終わりました */ /****************⑤ここまで ******************/ 非同期であればfunc3, func2, func1の順番でconsole.log()が出力されるはずですが、記述順に同期的に出力されました。
juner

2024/10/01 06:26

javascript の メインスレッドは シングルスレッドなので 長々とした同期処理はそのまま実行されているので 注意です。 Promiseのコンストラクタは同期処理なので 非同期になりません。できるなら async function 上に書いて for の中で await Promise.resolve() してください
int32_t

2024/10/01 06:32

「本来の処理内容」を具体的に書いたほうが的確な助言ができると思いますよ。「1000000000回ループを回す」が本当にしたいことではないですよね。 「本来の処理内容に非同期なものが」というのは、HTTPのレスポンス待ちのように「何か起きるまで待つ」処理があるという意味です。「1000000000回ループを回す」のように何も待つことがなくひたすら計算するものはワーカーを使わない限り同時実行はできません。
juner

2024/10/01 06:35

処理の合間に await Promise.resolve() もしくは await new Promise(resolve => setTimeout(resolve)); を挟むことで 前者 は連続したキューとして区切り、 後者は 画面再描画を含めて区切り 実行できるので もっと await した方がよさそうですね。
tada_tadaa

2024/10/01 07:13

>「本来の処理内容に非同期なものが」というのは、HTTPのレスポンス待ちのように「何か起きるまで待つ」処理があるという意味です。「1000000000回ループを回す」のように何も待つことがなくひたすら計算するものはワーカーを使わない限り同時実行はできません。 HTTPのレスポンス待ちのようなものならうまくいく印象がありますが、HTTPのレスポンスだって、promiseとかを用いているのでは?であるならば、「1000000000回ループを回す」の処理だって、Promiseとか関数をうまく用いればHTTPのレスポンス待ちのようにうまく非同期が実現できそうな気がするのですが、ダメなのでしょうか?
int32_t

2024/10/01 07:43

非同期処理を扱いやすく書くための手段がPromiseです。Promiseを使えば同期処理が非同期や並列処理になるわけではありません。 > うまく非同期が実現できそうな気がする やりたいことは非同期処理ではなく並列処理ではありませんか? 依然として「本当にやりたいこと」が不明なので、的確な助言がしにくいです。
maisumakun

2024/10/01 07:50

> Promiseとか関数をうまく用いればHTTPのレスポンス待ちのようにうまく非同期が実現できそうな気がするのですが、ダメなのでしょうか? そうですね、その処理の「途中に」awaitを入れるなどの書き換えを行えるなら分割は可能です(が、すでに「それでは煩雑になる」とそのやり方は除外されていますよね?)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問