2

この質問がさまざまな方法で何度も尋ねられたことは知っていますが、次の問題に対する適切な解決策を見つけるのにまだ苦労しています.

外部関数から戻る前に、この非同期的に実行される内部関数のコールバックが完了するのを待つにはどうすればよいですか?

function outer() {
    var result = false;
    var innerAsynch = function() {
        result = true;
    }
    setTimeout(innerAsynch, 1000);
    waitForInnerAsynch(); //blocking
    return result;  //true
}

1) 私はこれが 99.999% のユースケースで悪い習慣であることをよく知っています。

2)このコードを完全に再構築してください...私の唯一の要件は、innerAsynch()が完了して次のテストに合格するまでブラウザをブロックする何かをouter()が返すことです:

 if(outer()) {
    //1 second later.... yippee!
 }

また、私はjQueryを使用していますが、プラグインを使用するのが本当に意味がない限り、プラグインを使用しないことをお勧めします. ありがとう!

アップデート

私の目標は、outer() への同期呼び出し内に引数なしで非同期実行を完全にカプセル化することです。

言い換えれば、これはうまくいくはずです:

<a href="something" onclick="return outer()">A very slow link</a>

おそらくこれは実際には不可能であり、その場合はコールバックを使用しても問題ありませんが、その理由をよりよく理解したいと考えています。

4

2 に答える 2

1

私の目標は、outer() への同期呼び出し内に引数なしで非同期実行を完全にカプセル化することです。

非同期実行とコールバックは、ブロックしないという唯一の理由で存在します。本当にブロックしたい場合は、非同期コードを使用しないでください。非同期関数に依存している場合は、コールバックを使用するようにコードを再構築してください。それは簡単です。

JavaScript はシングルスレッドであるため、ブロックすると、コードのブロックが解除されるまでブラウザーがフリーズしたように見えます。ブロックすると、UI を更新して、長時間実行される操作が実行されていることをユーザーに通知することさえできなくなります。それが悪い理由です。この言語は、イベント ループと非同期イベントのキューを中心に設計されていることに注意してください。それに逆らおうとすると、大きな頭痛の種になるだけです。

于 2012-11-12T18:51:44.430 に答える
1

標準の js パターン。コールバックを使用するだけです:

function outer(callback) 
{
    var innerAsynch = function(innerCallback) {
        var result = true;
        innerCallback(result);
    }

    setTimeout(function()
    {
      innerAsynch(function(result)
      {
        callback(result);
      });

    }, 1000);
}

使用法:

outer(function(result)
{
  if ( result )
    //true
  else
    //false
});
于 2012-11-12T17:55:15.270 に答える