Javascript jQuery';s when.apply和包装异步函数
我的代码需要等待不同数量的服务器响应,并通过requireJS加载几个javascript模块 我想利用jQuery的when.apply。不幸的是,代码的.then()部分总是在我的任何回调之前执行 以下是我的代码摘要:Javascript jQuery';s when.apply和包装异步函数,javascript,jquery,asynchronous,jquery-deferred,Javascript,Jquery,Asynchronous,Jquery Deferred,我的代码需要等待不同数量的服务器响应,并通过requireJS加载几个javascript模块 我想利用jQuery的when.apply。不幸的是,代码的.then()部分总是在我的任何回调之前执行 以下是我的代码摘要: // load module func function loadRequireJsModule(arg, callback) { require([arg], callback); } // get layer info from server func fu
// load module func
function loadRequireJsModule(arg, callback) {
require([arg], callback);
}
// get layer info from server func
function getLayerInfoFromServer(arg, callback) {
var layerInfoListener = new DataLayer([arg]);
layerInfoListener.addRetrievedCallback(callback);
layerInfoListener.retrieveLayerInfo();
}
tasks.push( $.Deferred( function() {
loadRequireJsModule( "./" + layerJSON.type, function( module ) {
layer.controller = module;
});
}));
for (i=0; i<layerJSON.views.length; i++) {
layer.views[i] = {};
// get renderer class from require.js
tasks.push( $.Deferred( function() {
loadRequireJsModule( "./impl/" + layerJSON.views[i].renderer, function( index ){
return function( module ) {
layer.views[index].renderer = new module();
}
}(i));
}));
// POST request for layerInfo
tasks.push( $.Deferred( function() {
getLayerInfoFromServer( {
request: "configure",
layer: layerJSON.layer,
configuration: layerJSON.views[i]
}, function( index ){
return function( dataLayer, layerInfo ) {
layer.views[index].dataService = new TileService( layerInfo );
}
}(i));
}));
}
$.when.apply($, tasks).then( function() {
...
}
//加载模块func
函数loadRequireJsModule(参数,回调){
需要([arg],回调);
}
//从服务器func获取图层信息
函数getLayerInfoFromServer(参数,回调){
var layerInfoListener=新数据层([arg]);
LayerFoliStener.addRetrievedCallback(回调);
layerInfoListener.retrieveLayerInfo();
}
tasks.push($.Deferred(function()){
loadRequireJsModule(“./”+layerJSON.type,函数(模块){
层控制器=模块;
});
}));
对于(i=0;iEdit),现在您已经公开了实际代码:
您没有正确使用$.Deferred()
您上下文中的典型用法如下所示:
var d;
var tasks = [];
for (var i = 0; i < len; i++) {
// create new deferred object
d = $.Deferred();
// put deferred into tasks object
tasks.push(d);
loadRequireJsModule( "./impl/" + layerJSON.views[i].renderer, function( index, deferred ){
return function( module ) {
layer.views[index].renderer = new module();
// now that this operation is done, resolve our deferred
deferred.resolve();
}
}(i, d));
}
$.when.apply($, tasks).done(function() {
// code executes here when all the deferreds
// have had `.resolve()` called on them
});
显然,您不必使用所有三个操作.done()
、.notify()
和.fail()
,或者您可以在中指定所有操作。然后()
-出于教育目的,我将这三个操作都包含在注释中
如果您需要其他类型的异步操作的帮助,而这些异步操作还没有创建自己的promise对象,那么如果您展示和描述实际操作,我将很乐意提供帮助。延迟一开始很难处理,但就像很多事情一样,一旦它最终被接受,实际上非常简单而且非常有用。编辑-否w您已经披露了实际代码:
您没有正确使用$.Deferred()
您上下文中的典型用法如下所示:
var d;
var tasks = [];
for (var i = 0; i < len; i++) {
// create new deferred object
d = $.Deferred();
// put deferred into tasks object
tasks.push(d);
loadRequireJsModule( "./impl/" + layerJSON.views[i].renderer, function( index, deferred ){
return function( module ) {
layer.views[index].renderer = new module();
// now that this operation is done, resolve our deferred
deferred.resolve();
}
}(i, d));
}
$.when.apply($, tasks).done(function() {
// code executes here when all the deferreds
// have had `.resolve()` called on them
});
显然,您不必使用所有三个操作.done()
、.notify()
和.fail()
,或者您可以在中指定所有操作。然后()
-出于教育目的,我将这三个操作都包含在注释中
如果您需要其他类型的异步操作的帮助,而这些异步操作还没有创建自己的promise对象,那么如果您展示和描述实际操作,我将很乐意提供帮助。延迟一开始很难处理,但就像许多事情一样,一旦它最终融入,实际上非常简单而且非常有用。有我发现了一种替代方法,用于在不使用数组的情况下处理并行承诺循环。相反,使用模式promise=$。when(promise,anotherPromise)
e、 例如,像这样的事情
// Start with an empty resolved promise - undefined does the same thing!
var promise;
for (i = 0; i < layerJSON.views.length; i++) {
layer.views[i] = {};
// get renderer class from require.js
promise = $.when(promise, loadRequireJsModule("./impl/" + layerJSON.views[i].renderer, function (index) {
return function (module) {
layer.views[index].renderer = new module();
}
}
));
}
// Now do something after all the promises are resolved
promise.then(function () {
// Do the next part
});
//从一个空的已解析承诺开始-undefined做同样的事情!
var承诺;
对于(i=0;i
本例假设您更改getLayerInfoFromServer
以返回承诺:
笔记:
- 这种技术的缺点是,各个承诺的返回值以相反的顺序嵌套在彼此之间,因此不是很有用。如果您只需要知道它何时完成了所有任务,那就太好了
我发现了一种替代方法,可以在不使用数组的情况下处理并行承诺循环。相反,使用模式promise=$。when(promise,anotherPromise)
e、 例如,像这样的事情
// Start with an empty resolved promise - undefined does the same thing!
var promise;
for (i = 0; i < layerJSON.views.length; i++) {
layer.views[i] = {};
// get renderer class from require.js
promise = $.when(promise, loadRequireJsModule("./impl/" + layerJSON.views[i].renderer, function (index) {
return function (module) {
layer.views[index].renderer = new module();
}
}
));
}
// Now do something after all the promises are resolved
promise.then(function () {
// Do the next part
});
//从一个空的已解析承诺开始-undefined做同样的事情!
var承诺;
对于(i=0;i
本例假设您更改getLayerInfoFromServer
以返回承诺:
笔记:
- 这种技术的缺点是,各个承诺的返回值以相反的顺序嵌套在彼此之间,因此不是很有用。如果您只需要知道它何时完成了所有任务,那就太好了
如果要使用$,请返回延迟对象或承诺。如果不正确使用$。延迟()
对于异步操作而言,这根本不起作用。难怪这不起作用。这根本不是使用延迟对象的方式。我可以尝试在我的答案中添加更多内容。如果要使用$,请返回延迟对象或承诺。
时,这不是正确使用$。延迟()
对于异步操作而言,这是毫无疑问的。这不起作用。这根本不是使用延迟对象的方式。我可以尝试在我的答案中添加更多内容。我使用$.Deferred()创建我的延迟对象,并将我的函数作为参数传递。函数回调被调用,但现在$when.apply.then从未执行。我使用调试器查看,我的所有任务都是延迟对象。@Pondwater-当单个任务完成或失败时,您的代码正在解析或拒绝延迟对象吗?$.when()当您传递给它的所有延迟对象都已解析时,
将调用它的.done()
处理程序。或者,如果任何延迟对象被拒绝,它将调用它的.fail()
处理程序。如果,则会立即调用()