使用 $.Deferred、promises 和 $.ajax 构建依赖响应映射
Using $.Deferred, promises, and $.ajax to build a dependency response map
我有一组需要请求的 JS 资源。必须保持顺序,并且响应必须按照我请求的顺序进行。以下请求按顺序进行,但我无法捕获整个请求的 .done() promise 回调。
我从我的对象调用 getScripts 方法:
var depArray = ['file1.js', 'file2.js', 'file3.js'];
getScripts(depArray, global_config.jspath + "/");
这在 $.Deferred() 嵌套的 $.when promise 中迭代数组...
getScripts : function(arr, path) {
var depMap = [];
$.Deferred(
$.map(arr, function(src) {
$.when(
$.ajax({
url: (path || "") + src + ".js",
success: function (data) {
depMap.push(data);
//return data;
}
}
)
).then(function() {
console.log("request complete...", (path || "") + src + ".js");
return true;
});
})
).done(
function() { alert('completely done!!!!'); }
);
},
警报 ('completely done!!!!') 立即触发,不等待 ajax 调用执行和完成。我需要 return 方法中的 depMap 数组,所以我有一个按顺序从调用中获得的所有响应的映射。
响应将是:
['contents from file1.js', 'contents from file2.js', 'contents from file3.js']
但我从来没有 depMap 可以在最后交出。承诺对我来说仍然有点莫名其妙。感谢任何帮助...
好的,需要进行一些清理。首先,删除 $.Deferred
- 不需要它,因为您已经有 $.when
承诺。然后你需要构建承诺数组并将其传递给 $.when
.
最后,它可以看起来像这样:
getScripts: function(arr, path) {
// map each promise to its resource and aggregate
return $.when.apply(null, arr.map(function(src) {
return $.ajax({url: (path || "") + src + ".js"});
})).then(function(){
return [].map.call(arguments, function(x){ return x[0]; }) // just the data
});
}
$.ajax()
函数 return 是一个 jqXHR
对象,它是一个 Promise。 $.when()
函数说它接受一个或多个 Deferred 对象,但它似乎要求它们只是 Promises,而不是完整的 Deferred 对象。因此,您不需要使用 $.Deferred()
为每个 ajax 请求创建 Deferred 对象。您可以只使用 $.ajax()
编辑的对象 return。您可以使用 $.map()
创建承诺数组,按照 ajax 调用的顺序。
最终,您的 getScripts()
函数不能 return depMap
数组,因为它是异步的。相反,它可以写入 return Promise,如下所示。
getScripts: function(arr, path) {
return $.when.apply($, $.map(arr, function(src) {
return $.ajax({ url: (path || '') + src + '.js' });
})).then(function() {
return (arr.length > 1)
? $.map(arguments, function(a) { return a[0]; })
: [arguments[0]];
});
},
有关如何从 $.when(...).then()
函数的参数构造 return 数组到其回调函数的信息,请参阅 this Whosebug answer。 (.done()
的相同信息适用于 .then()
。)
我有一组需要请求的 JS 资源。必须保持顺序,并且响应必须按照我请求的顺序进行。以下请求按顺序进行,但我无法捕获整个请求的 .done() promise 回调。
我从我的对象调用 getScripts 方法:
var depArray = ['file1.js', 'file2.js', 'file3.js'];
getScripts(depArray, global_config.jspath + "/");
这在 $.Deferred() 嵌套的 $.when promise 中迭代数组...
getScripts : function(arr, path) {
var depMap = [];
$.Deferred(
$.map(arr, function(src) {
$.when(
$.ajax({
url: (path || "") + src + ".js",
success: function (data) {
depMap.push(data);
//return data;
}
}
)
).then(function() {
console.log("request complete...", (path || "") + src + ".js");
return true;
});
})
).done(
function() { alert('completely done!!!!'); }
);
},
警报 ('completely done!!!!') 立即触发,不等待 ajax 调用执行和完成。我需要 return 方法中的 depMap 数组,所以我有一个按顺序从调用中获得的所有响应的映射。
响应将是:
['contents from file1.js', 'contents from file2.js', 'contents from file3.js']
但我从来没有 depMap 可以在最后交出。承诺对我来说仍然有点莫名其妙。感谢任何帮助...
好的,需要进行一些清理。首先,删除 $.Deferred
- 不需要它,因为您已经有 $.when
承诺。然后你需要构建承诺数组并将其传递给 $.when
.
最后,它可以看起来像这样:
getScripts: function(arr, path) {
// map each promise to its resource and aggregate
return $.when.apply(null, arr.map(function(src) {
return $.ajax({url: (path || "") + src + ".js"});
})).then(function(){
return [].map.call(arguments, function(x){ return x[0]; }) // just the data
});
}
$.ajax()
函数 return 是一个 jqXHR
对象,它是一个 Promise。 $.when()
函数说它接受一个或多个 Deferred 对象,但它似乎要求它们只是 Promises,而不是完整的 Deferred 对象。因此,您不需要使用 $.Deferred()
为每个 ajax 请求创建 Deferred 对象。您可以只使用 $.ajax()
编辑的对象 return。您可以使用 $.map()
创建承诺数组,按照 ajax 调用的顺序。
最终,您的 getScripts()
函数不能 return depMap
数组,因为它是异步的。相反,它可以写入 return Promise,如下所示。
getScripts: function(arr, path) {
return $.when.apply($, $.map(arr, function(src) {
return $.ajax({ url: (path || '') + src + '.js' });
})).then(function() {
return (arr.length > 1)
? $.map(arguments, function(a) { return a[0]; })
: [arguments[0]];
});
},
有关如何从 $.when(...).then()
函数的参数构造 return 数组到其回调函数的信息,请参阅 this Whosebug answer。 (.done()
的相同信息适用于 .then()
。)