5

setTimeout コールバック内で設定された後にのみ、変数を返そうとしています。これを行う他の方法は考えられませんでしたが、これが私の試みです (コードがばかげているように見えることはわかっていますが、Cordova のバグを回避するためです)。私の理解を超えた理由で、無限ループになります。

function isConnected() {
    var done = false;
    setTimeout(function() {
        done = true;
    }, 500);

    while (!done) {}
    return navigator.connection.type!== Connection.NONE;
}

なぜこれが起こっているのかを説明したり、代替案を提供したりできますか?

更新(解決策):

function isConnected(callback) {
    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);
}


isConnected(function(connected) {
    if (!connected)
        alert('Not Connected');
});
4

3 に答える 3

7

その方法で問題を解決することはできません。javascript はシングル スレッドであるため、setTimeout コールバックは JS スレッドの実行が終了したときにのみ実行できるため、無限ループでは決して実行されず、コードがハングします。最終的に、ブラウザーは JS の実行時間の長い部分について不平を言い、それをシャットダウンするよう提案します。

代わりに、 でコールバック関数を使用し、setTimeout()そのコールバックからコードを継続する必要があります。タイムアウトにシーケンシャル コードを使用することはできません。非同期コーディング スタイルを使用する必要があります。

コールバックを渡すと、コールバックが呼び出され、接続されたブール値が渡されます。

function GetConnectedState(callback) {

    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);

}

既存のコードは、接続状態を 1/2 秒で確認する以外に何も提供していないようです。JavaScript での実際の種類の非同期操作 (ajax 呼び出しや websocket 接続など) では、操作が実際にいつ/完了したかを通知する成功または完了コールバックも存在する必要があり、に基づいてコールバックをトリガーすることもできます。それ(ほとんどの場合、1/2 秒よりも早い)。したがって、これは実際には完全なソリューションのようには見えませんが、使用していることを示すのはこれだけです。

たとえば、画像が正常にロードされたときにコールバックを呼び出し、エラーが発生したり、タイムアウトして応答がなかったりする答えを次に示します。Javascript Image Url VerifyおよびHow to implement a "function timeout" in Javascript - not just the ' setTimeout' . 他のタイプの非同期呼び出しで独自のタイムアウトを実装するために、同様の概念を使用できます。

于 2013-11-14T19:27:39.167 に答える
4

Javascript はシングルスレッドです。タイムアウト関数は、スクリプトがメイン イベント ループに戻るまで実行できません。しかし、あなたがループにいる限りwhile決して戻らないので、タイムアウト関数は決して実行されないので、 にdone設定されることはありませんtrue.

Javascript では、戻る前に非同期イベントを待機することはできません。

于 2013-11-14T19:24:56.190 に答える