これは奇妙な問題です。 Crockford風のパブリック/プライベートメンバーを使用して構築しているクライアントオブジェクトがあります。
var client = function() {
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
remote_data = jsonRequest1();
other_data = jsonRequest2();
return that;
};
私が抱えている問題は、新しい 'that'オブジェクト(準備ができているクライアントに信号を送る)を返す前に、いくつかのリモートJSONリソースをロードする必要があることです。データは非同期で(明らかに)返されます。ブール変数を設定して、各リモートリソースがいつ返されるかを示します。
私は次のようなことをすることを考えました:
return whenInitialized(function() { return that; });
WhenInitialized関数は、両方のブールフラグが真であるかどうかを返します。これをsetIntervalと組み合わせて使用しますが、これは機能しないと確信しています。
あなたの提案をいただければ幸いです。
コードを実行するにはafter非同期操作が成功したため、continue。これは、操作が完了したときにコードが呼び出す単なるコールバックにすることができます。
このようなもの:
var client = function(done) { // done is the callback
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
var done1 = false, done2 = false;
var complete1 = function() { done1 = true; if (done2) done(); };
var complete2 = function() { done2 = true; if (done1) done(); };
remote_data = jsonRequest1(complete1);
other_data = jsonRequest2(complete2);
return that;
};
しかし、これらの制御フラグは本当に煩わしく、実際にはスケーリングしません。これを行うためのより良い宣言的な方法は、 jQuery deferreds :のようなものを使用することです。
$.when(jsonRequest1(), jsonRequest2()).then(done);
非同期が終了するのを待つために、ループ(オプションでタイムアウト付き)を実行できます。警告、これは(要求に応じて)他のすべての機能をブロックし、時間がかかりすぎるとブラウザがフリーズする可能性があります。ただし、このようにブロックするのではなく、必要なことを実行する非同期の方法を実際に理解する必要があります。
var syncRequest = function(options) {
var is_finished = false;
var result;
var finished_callback = function(response) {
is_finished = true;
result = response.result;
}
ajax_request(options, finished_callback);
// timeout in 30 seconds
var timeout = (new Date()).getTime() + 30000;
while ( !is_finished ) {
if ( (new Date()).getTime() >= timeout ) {
alert('Request timed out');
}
// do nothing, just block and wait for the request to finish
}
return result;
}