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

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

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

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

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

Q&A

解決済

2回答

631閲覧

javascriptで同期処理をしたい。

One_of_Arthur

総合スコア82

JavaScript

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

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

0グッド

0クリップ

投稿2021/08/28 10:00

編集2021/08/28 10:07

前提・実現したいこと

javascriptで同期処理をしたい。
今記述している内容でうまくいくと思ったのですが、違うようで意図する結果になりません。
今作っているページで、javascript部分が肥大化して来ていて、見た目の順番通りに進行しなくなってきました。
「.then」と「new Promise」で解決しようとしているのですけれど、うまくいきません。
アドバイスをください。よろしくお願いします。

発生している問題

現状は、先にいくつか「ここまでは来てる 021」が表示されたあと、「ここまでは来てる 070」が表示されて、
以降の再帰で「ここまでは来てる 021」が表示されている。
だが、再帰が全て終了したあとで、「ここまでは来てる 070」に行きたい。

該当のソースコード

javascript

1 function displayList(){ 2 return new Promise(function(resolve,reject){ 3 alert('ここまでは来てる 070'); 4//省略 5 resolve(); 6 }); 7 } 8 9 function recursionProc(){ 10 alert('ここまでは来てる 021'); 11//省略...一定の条件下で再帰させている 12 setTimeout(recursionProc, 100); 13 return; 14//省略 15 } 16 17 function progressProc(){ 18 return new Promise(function(resolve,reject){ 19//省略 20 recursionProc(); 21//省略 22 resolve(); 23 }); 24 } 25 26//省略 27 progressProc() 28 .then(displayList); 29//省略

試したこと

ググって、色々試行錯誤をして、この記述に行き着きました。
「function recursionProc(){}」も「new Promise」にしてみましたが、うまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

サーバー:ロリポップ
ブラウザ:FireFox 91.0.2 (64 ビット)
クライアント:macOS Mojave 10.14.6

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

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

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

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

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

guest

回答2

0

自己解決

解決したみたいです。
「setTimeout」の解釈が間違っていたようです。
「.then」と「new Promise」を使っても「await」を付けても、終了するまで待たずに先に進んでしまうみたいで、
そのあとでタスクキューに入れられている処理(setTimeoutで指定した関数)を処理するようです。

そこで、
「setInterval」に変えて、「recursionProc」の内容を「progressProc」の中に組み替えました。
他にもいくつかバグが有って修正しましたけれど、以下のようにしたら意図通りの順番になりました。

javascript

1 function progressProc(){ 2 return new Promise(async function(resolve,reject){ 3//省略 4 const intervalID = await setInterval(() =>{ 5//省略・・・キャンセルした場合{ 6 clearInterval(intervalID); 7 reject(); 8 } 9//省略・・・繰り返したい処理をここに記述 10//省略・・・正常に終了する場合{ 11 clearInterval(intervalID); 12 resolve(); 13 } 14 }, 100); 15 }); 16 } 17 18//省略 19progressProc() 20 .then(displayList); 21//省略

アドバイスを頂いた方々、有難うございました。
アドバイスをそのまま実行しても上手くできず(おそらく私のスキル不足)、アドバイスとは違う形になってしまったので、自己解決とさせていただきます。

投稿2021/08/29 09:18

One_of_Arthur

総合スコア82

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

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

0

掲載されたコードだと、
recursionProc();の直後にresolve()してしまっているので、
その後then()の処理が行われてしまいます。

displayListでPromiseを使っても、待つコードがないのですぐに実行されてしまうので、
あまり意味がないです。

再帰がどのような条件で終わるかコードでは分かりませんが、

function displayList(){ alert('ここまでは来てる 070'); } function recursionProc(){ alert('ここまでは来てる 021'); setTimeout(recursionProc, 100); return; } function progressProc(){ return new Promise(function(resolve,reject){ recursionProc(); if (再帰が終わったら) { resolve(); } }); } progressProc() .then(displayList);

のようになるのかなと思います。

投稿2021/08/28 10:29

sassy

総合スコア45

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

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

One_of_Arthur

2021/08/29 06:19

有難うございます。上手く行きません。 頂いたコードだと、「if」も再帰させるかループさせる必要があるのでしょうか。 少し変えてみました。未だ解決せずですが、再帰している「recursionProc」は省略無しにするとこうなります。 「progressProc」の中から「recursionProc」を呼ぶ必要がなかったので、外に出して「.then」にし、 「recursionProc」を呼ぶのを外に出しました。 ```javascript function recursionProc(){ return new Promise(function(resolve,reject){ alert('ここまでは来てる 021'); var e_time = new Date(); var diff = Math.floor((e_time.getTime() - s_time.getTime()) / 1000); if (diff > timeoutSecond || flgCancel){ if(diff > timeoutSecond){ timeoutAlert(); } endingProc(); reject(); } countUp = fRead(); document.getElementById('example3').innerHTML = countUp; if (document.getElementById('progress1').value < document.getElementById('tweetNumber').value ) { document.getElementById('progress1').value = countUp; alert('ここまでは来てる 023'); setTimeout(recursionProc, 100); }else{ startButton.disabled = false; //処理が完了したらボタンを活性状態に戻す cancelButton.disabled = true; //キャンセルボタンを無効にする } resolve(); }); } progressProc() .then(recursionProc) .then(displayList); ```
One_of_Arthur

2021/08/29 06:20

見づらくなってしまいました。すみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問