0

私はSalesForce上に構築されたHTML5モバイルWebアプリに取り組んでいます。JavaScript Remoting関数を多用しているので、これらのリモート関数呼び出しのN個(複数)が完了するのを待ってから、別のイベントまたは関数呼び出しを発生させる方法を知りたいと思います。私たちが達成しようとしているユースケースは次のとおりです。

  1. $ .mobile.showPageLoadingMsg();を使用してjQueryスピナー/ローダーを表示します。
  2. リモート関数1、2、3、...、Nを呼び出します。
  3. リモート機能1、2、3、...、Nが戻るのを待ちますが、ブラウザをフリーズしないでください。
  4. $ .mobile.hidePageLoadingMsg();でjQueryスピナー/ローダーを非表示にします。

    // Show a Loading Spinner while we wait for our remote requests to complete.
    $.mobile.showPageLoadingMsg();
    
    // Remote Request 1
    MyController.f1(
        function(result, event){
            if(event.type == 'exception') {
                alert('Error: ' + event.message);                     
            } else {
                // Do stuff here such as fill in a form with the results from f1
            }
        },
        {escape:true});
    
    // Remote Request 2
    MyController.f2(
        function(result, event){
            if(event.type == 'exception') {
                alert('Error: ' + event.message);                     
            } else {
                // Do stuff here such as fill in a form with the results from f2
            }
        },
        {escape:true});
    
    // ...
    
    // Remote Request N
    MyController.fN(
        function(result, event){
            if(event.type == 'exception') {
                alert('Error: ' + event.message);                     
            } else {
                // Do stuff here such as fill in a form with the results from fN
            }
        },
        {escape:true});
    
    // I want to wait until all of my requests to finish before I hide the loading spinner.
    wait_for_all(); 
    $.mobile.hidePageLoadingMsg();  
    
4

2 に答える 2

2

これが私がこのケースを一般的に処理する方法です:

    function doManyAsync(doneCallback) {
        // Async worker counters
        var workers = 0;

        function tickWorkers() {
            workers--;
            if ( workers === 0 ) {
                if ( doneCallback )
                    doneCallback();
            }

        }

        // Queue off first one
        doAsyncFunc1(1,2,3, tickWorkers);
        workers++;

        // Queue off second
        doAsyncFunc2(function() {
            tickWorkers();
        });
        workers++;
        
    }

非同期ワーカーカウンターは、それらを追跡するために非同期関数のスコープ外で使用されます。開始された非同期関数ごとに、カウンターをインクリメントします。それらが終了すると、コールバックはすべて完了するまでデクリメントし、終了したコールバックを呼び出します。これは、すべての関数の増分に依存しています。非同期関数が失敗するリスクがある場合は、タイムアウトを設定してワーカー数を時々チェックし、しきい値を超えて0ではない場合は、必要に応じて失敗するかエラーを生成します。

コードでどのように見えるかを次に示します。

    function doManyAsync(doneCallback) {

        // Async worker counters
        var workers = 0;

        function tickWorkers() {
            workers--;
            if ( workers === 0 ) {
                if ( doneCallback )
                    doneCallback();
            }

        }

        // Remote Request 1
        MyController.f1(
            function(result, event){
                tickWorkers();
                if(event.type == 'exception') {
                    alert('Error: ' + event.message);                     
                } else {
                    // Do stuff here such as fill in a form with the results from f1
                }
            },
            {escape:true});
        workers++;

        // Remote Request 2
        MyController.f2(
            function(result, event){
                tickWorkers();
                if(event.type == 'exception') {
                    alert('Error: ' + event.message);                     
                } else {
                    // Do stuff here such as fill in a form with the results from f2
                }
            },
            {escape:true});
        workers++;

        // ...

        // Remote Request N
        MyController.fN(
            function(result, event){
                tickWorkers();
                if(event.type == 'exception') {
                    alert('Error: ' + event.message);                     
                } else {
                    // Do stuff here such as fill in a form with the results from fN
                }
            },
            {escape:true});
        workers++;

    }

    // You would then
    $.mobile.showPageLoadingMsg();
    doManyAsync(function() {
        $.mobile.hidePageLoadingMsg();
    })
于 2012-08-30T23:15:14.063 に答える
0

jQueryのwhenおよびdone関数を使用してみてください。

$.when(asyncFunc1, asyncFunc2).done(yourCallbackHere)

このようにして、最初の句のすべてのアクションが完了したときにコールバック関数が呼び出されます。

donethenに置き換えることもできます。コールバックは、提供された遅延オブジェクトが解決されたか拒否されたかに関係なく呼び出されます。

これはあなたが試すことができる何かの簡単な例です:

// Remote Request 1
MyController.f1(
  function(result, event){
    var dfr = $.Deferred(); // New deferred object.
    if(event.type == 'exception') {
        dfr.reject(); // Error, object should be rejected.
    } else {
        // Do stuff here such as fill in a form with the results from f1
        dfr.resolve(); // Success, object is resolved.
    }
    return dfr; // Return the deferred object.
});

当然のことながら、f1関数は内部コールバックと同じ結果を返さない場合がありますdfr。もしそうなら、これは今やもっともらしいです:

$when(MyController.f1).done(successCallback); // Callback only if resolved.
$when(MyController.f2).then(alwaysCallback); // Callback if resolved or rejected.
于 2012-08-30T23:20:12.013 に答える