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