javascriptにおいて、ある関数を排他的に使われるようにして同時に実行
されないうようにしたいのですが、どのようにしたらよいでしょうか?
完全にブロックできれば理想ですが、1秒遅延させられればそれでも十分です。
私が試したのは以下のように「実行中フラグ」みたいなのをセットしてフラグがtrueの場合はsetTimeoutで処理を1秒遅らせるというように試してみたのですが、複数呼び出すと同時に実行されてうまくいきませんでした。。
var is_processing = false; function somefunc() { var wait = 0; if (is_processing == true) { wait = 1000; } setTimeout(function() { // 処理 is_processing = true; do_something(); }, wait); is_processing = false; }
お手数ですがご教示いただけますと助かります。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/17 03:05

回答3件
0
ベストアンサー
フラグ管理
同期処理である限りは多重実行されませんが、非同期処理でしょうか。
JavaScript
1'use strict'; 2const something = ((executed) => function something () { 3 if (executed) { 4 throw new Error('something() can not be executed in duplicate'); 5 } 6 7 executed = true; 8 9 console.log('実行中'); 10 11 executed = false; 12})(false); 13 14something();
ご存知とは思いますが、変数 executed
の処理中フラグは非同期処理が完了したタイミングで変更してください。
タイマー管理
回答いただいたところ恐縮なのですが、Errorを出すとその呼出が失敗してしまうかと思います。。呼び出しに対して実行はしないといけないのですが、同時に実行するのは避けたいというところなのです・・・。
setTimeout
なら仕様上、排他処理されます。
実行タイミングは前処理が終わった直後ですが、期待するタイミングが異なるなら自前で制御する必要があります。
JavaScript
1function something (string) { 2 console.log(string); 3} 4 5setTimeout(something, 1000, 1); 6setTimeout(something, 1000, 2);
window.setTimeout() + Queue
どんな場面かといいますとチャットメッセージを受信して画面にappendで追加するのですが、その処理を1個ずつ追加するようにしたいのですが、ほぼ同時に関数が呼ばれるといっぺんに追加されてしまうので、それを間を置いて追加されるようにしたいのです。。
それは「同時に実行」ではなく、「処理間隔が0もしくは0に近い状態」で連続的に実行されています。
関数をキュー管理してやれば、解決可能です。
JavaScript
1const setTimeQueue = ((handleTimeout) => { 2 const queue = []; 3 4 return function setTimeQueue (fn, args) { 5 queue.push({fn: fn, args: args}); 6 7 if (queue.length === 1) { 8 setTimeout(handleTimeout, 500, queue, 500); 9 } 10 }; 11})(function handleTimeout (queue, delayTime) { 12 const entry = queue.shift(); 13 14 entry.fn(...entry.args); 15 16 if (queue.length) { 17 setTimeout(handleTimeout, delayTime, queue, delayTime); 18 } 19}); 20 21const consoleLog = console.log.bind(console); 22 23setTimeQueue(consoleLog, [1]); 24setTimeQueue(consoleLog, [2]); 25setTimeQueue(consoleLog, [3]);
Re: koyon さん
投稿2018/06/17 03:02
編集2018/06/17 12:29総合スコア18194
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
javascript
1var is_processing = false; 2const wait = 1000; // <------------------- 別に定数でよい気がする 3 4function somefunc() { 5 //var wait = 0; // <------------------- 定数化したら不要 6 if (is_processing == false) { // <----- 処理中でなかったらsetTimeoutすればいいんでは? 7 setTimeout(function() { 8 // 処理 9 is_processing = true; 10 do_something(); 11 is_processing = false; // <------ 処理が終わったらflag-OFF 12 }, wait); 13 } 14 // is_processing = false; // <--------- これはいらんでしょ。 15}
投稿2018/06/17 04:56
編集2018/06/17 05:01総合スコア5572
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
setTimeoutした後に(タイマーセットしただけでdo_something();が実行されてないのに)
is_processing = false;してるのが問題のように思います。
最後のis_processing = false;は消して
setTimeoutは下記ではないでしょうか?
setTimeout(function() { // 処理 is_processing = true; do_something(); is_processing = false; }, wait);
投稿2018/06/17 03:49
総合スコア508
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。