5

たとえば、内部にランダムなコードを持つ2つの関数があり、ユーザーのシステム(低速、中速、高速)に基づいて、2つの関数が完了するまでにかかる時間を知る方法がない場合setTimeout、完了後にfunction2のみ発砲しようとする場合は実用的ではありません。 function1

時間の要件が何であれ、両方の関数が100%非jQuery関数であり、内部にjQueryコードがないため、jQueryで完全に監視できないことを考慮して、どのように使用jQuery.deferredしてfunction2発火させることができますか? function1せいぜい、関数には.css()、時間の関連付けがなく、古いコンピューターでは実行速度が遅くなる可能性があるjQueryメソッドが含まれている可能性があります。

次のように呼び出すのと同じように、それfunction2が同時に実行されていないことを確認するにはどうすればよいですか。function1

function1(); function2();

を使用して$.deferred?それ以外の回答$.deferredも大歓迎です!

3月20日追加: function1()がラムダ関数であり、ユーザー入力に応じて、関数に非同期呼び出しがある場合とない場合があり、関数が実行する操作の数を判断できない場合はどうなりますか?これは、次に何が起こるかについての手がかりがない関数ですが、何があっても、ラムダ関数(function1)からのすべてが完了した後にのみ、function2を実行する必要があります。時間がかかりますが、非同期の側面が完了する限り。これはどのように達成できますか?

3月22日追加: つまり、私が求めていることを実行する唯一の方法は、匿名関数をコールバックとして、実行後にコールバックを実行する非同期関数に渡すか、または必要なときに実行するイベントリスナーを作成することだと思います。イベントが最終的にトリガーされます。

アクションの実際の実行を処理するために、前述の関数を含むフレーム内にメカニズム(イベントハンドラー)を手動で構築せずに、2つの別々の行で非同期呼び出しを実行し、それらを順番に起動する方法は実際にはありません。

これらのタイプのメカニズムの良い例は、jQueryの.queue()メソッドと$.Defferredオブジェクトです。

.queue()以下の回答は、 ingと使用に関するjQueryのAPIを読み、$.Deferredこれを明確にするのに役立ちました。

Tgrは、jQueryの$.Deferredオブジェクトを使用してカスタムチェーン可能関数を作成する方法について以下の優れた例を示しました。カスタム関数自体には、必ずしもjQueryコードが含まれている必要はありません。これは、まさに私が探していたものです。

4

2 に答える 2

6
function first(deferred) {
    // do stuff
    deferred.resolve();
}
function second() {
    // do stuff
}

$.Deferred(first).then(second);

しかし、Tomalakが指摘したように、非常にトリッキーなfirstこと(Webワーカーの利用など)を行わない限り、これは不要です。

更新

基本的な考え方は、即時ではないことを行うときはいつでも、Deferredオブジェクトを作成し、それを返すというものです。(jQueryのAJAX呼び出しはすでにこれを行っています。)その後、Deferred.thenを使用して、フォローアップ操作を遅らせることができます。

function first() {
    var deferred = $.Deferred();
    var callback = function() {
        deferred.resolve();
    }
    // do immediate stuff
    someAsyncOperation(callback);
    return deferred.promise(); // turns the Deferred into a Promise, which
                               // means that resolve() will not be accessible
}

function second() {
    // do stuff
}

first().then(second); // or: $.when(first).then(second)

secondが非同期操作でもある場合は、$.whenのマージ機能を使用できます。

function second() {
    var anotherDeferred = $.Deferred();
    // do stuff with anotherDeferred
    return anotherDeferred.promise();
}

$.when(first(), second()).then(third); // third will run at the moment when 
                                   // both first and second are done
于 2011-03-19T09:59:57.660 に答える
5

JavaScript自体は非同期ではありません。シングルスレッド、同期です。

function1();
function2();

非同期呼び出しが含まれていない限り、次々に実行されます。onSuccessその場合、( XmlHttpRequestのように)渡すことができるコールバックが常にあります。そこに2番目の関数を配置します。

実は、非同期ビットが含まれていても、厳密に次々と実行されます。関数の残りの部分が終了しているときに、非同期ビットがまだ終了していない可能性があるだけです。


jsFiddleの例を編集し、修正しました(参照):

function foo() {
  $('#foo')
  .html('<span>foo1</span>')
  .animate(
    {              /* properties */
      left: '100px' 
    },      
    360,           /* duration */
    'swing',       /* easing */
    function () {  /* "complete" callback */
      $('#foo').append('<span>foo2</span>');
      bar();
    } 
  );
}

私が言ったように。渡すことができるコールバックは常にあります。

于 2011-03-19T09:12:32.670 に答える