javascriptループ内にタイムアウト/スリープ関数を追加
私はjsファイル内にスリープ/遅延関数を追加しようとしています、これは:
var webTest = function()
{
let regex = /^https?:\/\//;
let url = $('#list_urls').val().split('\n');
var xmlhttp = [], i;
var myObj2 = [], i;
for(let i = 0; i < url.length; i++)
{
(function(i) {
xmlhttp[i] = new XMLHttpRequest();
url[i] = url[i].replace(regex, '');
xmlhttp[i].open("GET", "https://website.com/API?key=<MY_API_KEY>&url="+url[i], false);
xmlhttp[i].onreadystatechange = function() {
if (xmlhttp[i].readyState === 4 && xmlhttp[i].status === 200) {
myObj2 = JSON.parse(xmlhttp[i].responseText);
document.getElementById("demo"+i).innerHTML = myObj2.results[1].categories;
}
};
xmlhttp[i].send();
})(i);
console.log(`The Server2: `+ myObj2);
}
}
私は、このスクリプトは、10秒間一時停止すると、再び仕事をし、再度10秒間一時停止すると、このそれまでは、テキストの長さがthatn大きい好きです私ループで!私のコードは、1回実行すると機能しますが、ループで実行すると機能しません。これは、WebサイトのAPIにレート制限があるため、スリープ機能を追加しようとしている理由です。
だから私が試したのはsleep()を待つことです。メソッドとsetTimeoutメソッドも試しましたが、ソートで期待どおりに機能していません。私のコードではまったく機能しません。
sleep();を待つ まったく機能せず、Uncaught SyntaxErrorのようなメッセージが表示されます:awaitは非同期関数と非同期ジェネレーターでのみ有効ですwebTestfile.js:27
回答
あなたはできるES6のを利用してasync/await-feature!
を使用するにはawait
、宣言された関数/式本体に含まれている必要がありますasync
。
基本的に、これにより関数が非同期になり、が実行Promiseされるのを待機します。を使用して、設定された遅延の後にPromiseが実行されるようにしsetTimeout()
ます。「設定された遅延の後」は「正確に後」を意味するのではなく、基本的に「できるだけ早く」を意味することに
注意してください。
これを行うことにより、非同期関数はpromiseが実行されるのを待ち、その間にコールスタックを解放して、他のコードを実行できるようにします。
この例の実行順序は次のとおりです(簡略化)。
sleepingFunc()
コールスタックに配置されます- 反復:
await
Promiseが実行されるようにするには、この呼び出しを一時停止します🡒コールスタックを解放します
- 反復:
- コールスタックに新しい電話をかける
- 最終的に、Promiseが実行され、終了します
await
🡒一時停止されたコールバックをコールスタックに配置します sleepingFunc()
終了するまで繰り返します
手順3でわかるように、他の通話が遅延よりも時間がかかる場合、一時停止された通話はその余分な時間を長く待たなければなりません。
function sleep(ms) {
return new Promise(resolveFunc => setTimeout(resolveFunc, ms));
}
async function sleepingFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sleep");
await sleep(1000);
}
}
function synchronousFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sync");
}
}
sleepingFunc();
synchronousFunc();
この実行スニペットは、条件が満たされるまで1秒ごとに1つのタスクを実行し、その後タイマーをクリアします。
const work = (i)=>{
console.log('doing work here ', i);
}
let counter = 0
const timer = setInterval(()=>{
if (timer && ++counter >= 10) {
clearInterval(timer)
}
work(counter);
}, 1000)