$.when.apply.done returns 不同的结果取决于数组的大小是一个还是多个
$.when.apply.done returns different results depending on whether the size of the array is one or many
我正在寻找有关执行多个 ajax 调用然后合并结果的最佳方式的小建议。我的问题是,根据 when 函数的文档,当有多个参数与只有一个参数时,它将以不同的方式映射结果参数。
https://api.jquery.com/jquery.when/
这导致代码如下所示。这张支票对我来说似乎很难看,据我所知,每次使用 $.when.apply 时都需要进行检查。有没有办法将延迟数组传递给 when 函数,以便输出具有一致的形状?
//Returns an array of promises that are simple ajax get requests
var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
$.when.apply($, getEventFramesPromises).then(function () {
var eventFrames;
//Now "arguments" will either be an array with three arguments it the length of the getEventFramesPromises ===1
if (getEventFramesPromises.length === 1) {
eventFrames = [arguments[0]];
} else {
//Or it will be an array of arrays where each item in the array represents a deferred result
eventFrames = _.map(arguments, function (args) {
return args[0];
});
}});
不确定为什么这个问题被否决。我认为这个问题是合理的,我指出了有问题的确切文档。所以我最终采纳了 Kevin 的建议并编写了一个快速辅助函数,它将提取 jquery 调用的结果,同时考虑到数组中只有一个值时的行为。
function extractValuesFromPromises() {
if (arguments.length === 3 && typeof arguments[2].then === 'function') {
return [arguments[0]];
} else {
return _.map(arguments, function (args) {
return args[0];
});
}
}
然后在你的代码中你可以这样做....
var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
$.when.apply($, getEventFramesPromises)
.then(extractValuesFromPromises)
.then(function (eventFrames) {
//Do whatever with ajax results
});
jQuery $.when()
可能是 jQuery 集中设计最差的 API。它不仅 return 是一种基于您传递给它的内容的不同数据类型,而且它甚至不接受数组作为参数,这是最常见和最灵活的使用方式。我建议的是一个简单的包装器,"fixes" 设计要保持一致:
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function(promises) {
if (!Array.isArray(promises)) {
throw new Error("$.all() must be passed an array of promises");
}
return $.when.apply($, promises).then(function () {
// if single argument was expanded into multiple arguments, then put it back into an array
// for consistency
var args = Array.prototype.slice.call(arguments, 0);
if (promises.length === 1 && arguments.length > 1) {
// put arguments into an array for consistency
return [args];
} else {
return args;
}
});
};
而且,这里有一个略有不同的实现,它也采用 $.ajax()
解析的三元素数组,并使其成为单个数据值,因此您解析的值只是一个简单的单个元素结果数组:
// jQuery replacement for $.when() that works more like Promise.all()
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function (promises) {
if (!Array.isArray(promises)) {
throw new Error("$.all() must be passed an array of promises");
}
return $.when.apply($, promises).then(function () {
// if single argument was expanded into multiple arguments, then put it back into an array
// for consistency
var args = Array.prototype.slice.call(arguments, 0);
var returnVal;
if (promises.length === 1 && arguments.length > 1) {
// put arguments into an array for consistency
returnVal = [args];
} else {
returnVal = args;
}
// now make Ajax results easier to use by making it be just an array of results, not an array of arrays
//
return returnVal.map(function(item) {
// see if this looks like the array of three values that jQuery.ajax() resolves to
if (Array.isArray(item) && item.length === 3 && typeof item[2] === "object" && typeof item[2].done === "function") {
// just the data
return item[0];
} else {
return item;
}
});
});
};
我正在寻找有关执行多个 ajax 调用然后合并结果的最佳方式的小建议。我的问题是,根据 when 函数的文档,当有多个参数与只有一个参数时,它将以不同的方式映射结果参数。 https://api.jquery.com/jquery.when/
这导致代码如下所示。这张支票对我来说似乎很难看,据我所知,每次使用 $.when.apply 时都需要进行检查。有没有办法将延迟数组传递给 when 函数,以便输出具有一致的形状?
//Returns an array of promises that are simple ajax get requests
var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
$.when.apply($, getEventFramesPromises).then(function () {
var eventFrames;
//Now "arguments" will either be an array with three arguments it the length of the getEventFramesPromises ===1
if (getEventFramesPromises.length === 1) {
eventFrames = [arguments[0]];
} else {
//Or it will be an array of arrays where each item in the array represents a deferred result
eventFrames = _.map(arguments, function (args) {
return args[0];
});
}});
不确定为什么这个问题被否决。我认为这个问题是合理的,我指出了有问题的确切文档。所以我最终采纳了 Kevin 的建议并编写了一个快速辅助函数,它将提取 jquery 调用的结果,同时考虑到数组中只有一个值时的行为。
function extractValuesFromPromises() {
if (arguments.length === 3 && typeof arguments[2].then === 'function') {
return [arguments[0]];
} else {
return _.map(arguments, function (args) {
return args[0];
});
}
}
然后在你的代码中你可以这样做....
var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
$.when.apply($, getEventFramesPromises)
.then(extractValuesFromPromises)
.then(function (eventFrames) {
//Do whatever with ajax results
});
jQuery $.when()
可能是 jQuery 集中设计最差的 API。它不仅 return 是一种基于您传递给它的内容的不同数据类型,而且它甚至不接受数组作为参数,这是最常见和最灵活的使用方式。我建议的是一个简单的包装器,"fixes" 设计要保持一致:
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function(promises) {
if (!Array.isArray(promises)) {
throw new Error("$.all() must be passed an array of promises");
}
return $.when.apply($, promises).then(function () {
// if single argument was expanded into multiple arguments, then put it back into an array
// for consistency
var args = Array.prototype.slice.call(arguments, 0);
if (promises.length === 1 && arguments.length > 1) {
// put arguments into an array for consistency
return [args];
} else {
return args;
}
});
};
而且,这里有一个略有不同的实现,它也采用 $.ajax()
解析的三元素数组,并使其成为单个数据值,因此您解析的值只是一个简单的单个元素结果数组:
// jQuery replacement for $.when() that works more like Promise.all()
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function (promises) {
if (!Array.isArray(promises)) {
throw new Error("$.all() must be passed an array of promises");
}
return $.when.apply($, promises).then(function () {
// if single argument was expanded into multiple arguments, then put it back into an array
// for consistency
var args = Array.prototype.slice.call(arguments, 0);
var returnVal;
if (promises.length === 1 && arguments.length > 1) {
// put arguments into an array for consistency
returnVal = [args];
} else {
returnVal = args;
}
// now make Ajax results easier to use by making it be just an array of results, not an array of arrays
//
return returnVal.map(function(item) {
// see if this looks like the array of three values that jQuery.ajax() resolves to
if (Array.isArray(item) && item.length === 3 && typeof item[2] === "object" && typeof item[2].done === "function") {
// just the data
return item[0];
} else {
return item;
}
});
});
};