多个javascript远程处理功能完成时的功能/事件

时间:2012-08-30 22:36:53

标签: javascript ajax asynchronous salesforce remoting

我正在开发一个基于SalesForce构建的HTML5移动网络应用程序。我们大量使用JavaScript Remoting函数,我想知道一种等待N(多个)这些远程函数调用完成然后触发另一个事件或函数调用的方法。我们试图完成的用例如下:

  1. 使用$ .mobile.showPageLoadingMsg()显示jQuery Spinner / Loader;
  2. 呼叫远程功能1,2,3,...,N。
  3. 等待远程功能1,2,3,...,N返回,但不要冻结浏览器。
  4. 使用$ .mobile.hidePageLoadingMsg()隐藏jQuery Spinner / Loader;

    // 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();  
    

2 个答案:

答案 0 :(得分: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);
        tickWorkers++;

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

    }

在异步函数的作用域之外使用异步工作计数器来跟踪它们。对于每个启动的异步函数,递增计数器。当它们完成时,回调将减少,直到它们全部完成并调用完成的回调。这取决于每个函数的递增。如果存在异步功能失败的风险,那么您可以设置超时以立即检查工作器计数,并且如果它超过阈值而不是0则则根据需要失败或生成错误。 / p>

以下是您的代码的外观:

    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});
        tickWorkers++;

        // 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});
        tickWorkers++;

        // ...

        // 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});
        tickWorkers++;

    }

    // You would then
    $.mobile.showPageLoadingMsg();
    doManyAsync(function() {
        $.mobile.hidePageLoadingMsg();
    })

答案 1 :(得分:0)

尝试使用jQuery 完成功能。

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

这样,当第一个子句中的所有动作都完成时,就会调用你的回调函数。

您也可以将完成替换为然后,无论提供的延迟对象是否已解决或拒绝,都会调用您的回调。

这是您可以尝试的一个简单示例:

// 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.