setTimeout
がどのように機能するかについて少し混乱しています。ループ内にsetTimeout
を入れようとしているので、ループの反復は、たとえば1秒離れています。ループが繰り返されるたびにHTTPリクエストが作成され、相手側のサーバーはこのような短い時間内にそれほど多くのリクエストを処理できないようです。
for (var i = 1; i<=2000 && ok; i++) {
var options = {
Host:'www.Host.com',
path:'/path/'+i
};
setTimeout(makeRequest(options, i), 1000);
};
なぜこれが機能しないのですか?どうすればこれを達成できますか?
ありがとうございました
あなたはこのようなものが必要です
_var counter = 5;
function makeRequst(options, i) {
// do your request here
}
function myFunction() {
alert(counter);
// create options object here
//var options = {
// Host:'www.Host.com',
// path:'/path/'+counter
//};
//makeRequest(options, counter);
counter--;
if (counter > 0) {
setTimeout(myFunction, 1000);
}
}
_
参照 このフィドル
alert(count);
の時点で、サーバーへの呼び出しを行うことができます。カウンターは反対に機能することに注意してください(カウントダウン)。私はあなたのことをどこで行うべきかいくつかのコメントで更新しました。
setTimeout は非ブロッキングであり、非同期です。あなたはそれにコールバックを与え、遅延が終わるとあなたのコールバックが呼び出されます。
いくつかの実装は次のとおりです。
setTimeout
コールバックで 再帰呼び出し を使用できます。
function waitAndDo(times) {
if(times < 1) {
return;
}
setTimeout(function() {
// Do something here
console.log('Doing a request');
waitAndDo(times-1);
}, 1000);
}
関数の使用方法は次のとおりです。
waitAndDo(2000); // Do it 2000 times
スタックオーバーフローエラーについて:setTimeout
呼び出しスタックをクリアする( この質問 を参照)ので、 setTimeout
再帰呼び出しでのスタックオーバーフローについて心配する必要があります。
すでに io.js ( ES6 を使用する「次の」Node.js)を使用している場合は、洗練されたソリューションを使用して、再帰せずに問題を解決できます。
function* waitAndDo(times) {
for(var i=0; i<times; i++) {
// Sleep
yield function(callback) {
setTimeout(callback, 1000);
}
// Do something here
console.log('Doing a request');
}
}
関数の使用方法は次のとおりです( co を使用):
var co = require('co');
co(function* () {
yield waitAndDo(10);
});
ところで:これは実際にループを使用しています;)
現在、スクリプトの実行からわずか1秒後に、すべてのリクエストが同時に発生するようにスケジュールしています。次のようなことをする必要があります。
var numRequests = 2000,
cur = 1;
function scheduleRequest() {
if (cur > numRequests) return;
makeRequest({
Host: 'www.Host.com',
path: '/path/' + cur
}, cur);
cur++;
setTimeout(scheduleRequest, 1000)
}
後続の各リクエストは、現在のリクエストが完了した後にのみスケジュールされることに注意してください。
上記で誰もこれについて言及していないことに驚いていますが、setTimeoutではなくsetIntervalが必要なようです。
vat poller = setInterval(makeRequestFunc, 3000)
上記のコードは、3秒ごとにリクエストを行います。オブジェクトを変数poller
に保存したので、次のようにオブジェクトをクリアすることでポーリングを停止できます。
cleanInterval(poller)
SetTimeout呼び出しでmakeRequest()を呼び出しています-関数を呼び出すのではなく、setTimeoutに関数を渡す必要があります。
setTimeout(makeRequest, 1000);
()なし
私はパーティーに遅れるかもしれませんが、ここにfor
ループを省略する必要のない別の(より読みやすい)解決策があります。
あなたのコードが行うことは、1秒後にsetTimeout
関数を呼び出す2000(実際には1999)のmakeRequest
オブジェクトを作成することですfrom now。ほら、他のsetTimeout
sの存在を知っている人はいません。
それらを互いに1秒離したい場合は、そのように作成する責任があります。
これは、counter(この場合はi
)とタイムアウトを使用して実現できますdelay。
for (var i = 1; i<=2000 && ok; i++) {
var options = {
Host:'www.Host.com',
path:'/path/'+i
};
setTimeout(makeRequest(options, i), i * 1000); //Note i * 1000
};
最初のタイムアウトオブジェクトは今から1秒に設定され、2番目のオブジェクトは2秒に設定されますこれからなど。意味1秒互いに離れている。