完成 ajax 调用数组的循环,而不是在其中一个调用出错时中断
Finish loop of ajax calls array instead of breaking on error from one of calls
我正在尝试从一个数组中进行 ajax 次调用循环,并保存每个数据结果,以便在成功接收到所有调用后打印出来。
问题是,如果有任何ajax调用返回错误,整个过程中止并且不执行回调。 (尝试使用 listWithErrorResult)
如何在不中断循环的情况下推送错误的内容?
var list = ['UQ13nr6urIo', 'hxa_Z0eZ83E', 'ulHB2mNlovg'];
var listWithErrorResult = ['UQ13nr6urIo', 'hxa_Z0eZ83E', 'IWEHeIdBkc4'];
var callback = function() {
console.log("done");
console.log(tracks);
};
var requests = [], tracks = [];
for(i = 0; i < list.length; i++) {
requests.push($.ajax({
url: 'http://www.youtubeinmp3.com/fetch/?format=JSON&video=https://www.youtube.com/watch?v='+list[i],
dataType: "json",
success: function(data) {
console.log('suc');
tracks.push(data);
},error: function() {
console.log('err');
tracks.push('err');
}
}));
}
$.when.apply(undefined, requests).then(function(results){callback()});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
您可以将 .then()
句柄附加到您的 ajax 调用并确保每个 ajax 调用都得到解决而不是拒绝。这将在最后为您提供一组结果,保证包含您所有的 ajax 调用。:
var callback = function(/* tracks are passed here as arguments */) {
console.log("done");
var tracks = Array.prototype.slice.call(arguments);
console.log(tracks);
};
var requests = [];
for(var i = 0; i < list.length; i++) {
requests.push($.ajax({
url: 'http://www.youtubeinmp3.com/fetch/?format=JSON&video=https://www.youtube.com/watch?v='+list[i],
dataType: "json",
}).then(function(data) {
return data;
}, function(err) {
// convert failure into success so $.when() doesn't stop
return $.Deferred().resolve('err');
}));
}
$.when.apply($, requests).then(callback);
您还可以使用我编写的 $.settle()
版本,它让所有承诺完成并为您提供所有结果,即使有些承诺被拒绝。
您可以使用这个新函数 $.settle()
而不是 $.when()
(在第一个被拒绝的承诺处停止),它 returns 您可以得到所有承诺的结果。它 returns 一组 PromiseInspection 对象,允许您查询每个承诺的已解决值或拒绝原因。
你使用 $.settle()
就像 $.when()
一样,除了它 returns 所有结果都在 PromiseInspection 对象中并且它总是解析(从不拒绝)。由于 jQuery 将多个参数传递给 .then()
处理程序(特别是 Ajax 调用)的非标准方式,如果 .settle()
检测到多个参数,它会将它们复制到一个数组中所以从成功的 ajax 调用返回的 PromiseInspection.value 是一个数组 [data, textStatus, jqXHR]
。这是 jQuery 非标准承诺中最糟糕的部分。大概这是 jQuery 3.x 中的 fixed/changed ,它应该符合标准。此代码将适用于任何一种,因为它会自动检测 .then()
处理程序是否发送了多个参数并将它们转换为单个数组参数。
// ES6 version of settle
jQuery.settle = function(promises) {
function PromiseInspection(fulfilled, val) {
return {
isFulfilled: function() {
return fulfilled;
}, isRejected: function() {
return !fulfilled;
}, isPending: function() {
// PromiseInspection objects created here are never pending
return false;
}, value: function() {
if (!fulfilled) {
throw new Error("Can't call .value() on a promise that is not fulfilled");
}
return val;
}, reason: function() {
if (fulfilled) {
throw new Error("Can't call .reason() on a promise that is fulfilled");
}
return val;
}
};
}
return $.when.apply($, promises.map(function(p) {
return p.then(function(val) {
if (arguments.length > 1) {
val = Array.prototype.slice.call(arguments);
}
return new PromiseInspection(true, val);
}, function(err) {
if (arguments.length > 1) {
err = Array.prototype.slice.call(arguments);
}
return new PromiseInspection(false, err);
});
}));
}
您还必须向 $.when.apply
then
添加错误回调,因为它是其中一个调用失败时的错误条件。
$.when.apply(undefined, requests).then(
function(results){callback()},
function(results){callback()}
);
工作 jsBin here
我正在尝试从一个数组中进行 ajax 次调用循环,并保存每个数据结果,以便在成功接收到所有调用后打印出来。
问题是,如果有任何ajax调用返回错误,整个过程中止并且不执行回调。 (尝试使用 listWithErrorResult)
如何在不中断循环的情况下推送错误的内容?
var list = ['UQ13nr6urIo', 'hxa_Z0eZ83E', 'ulHB2mNlovg'];
var listWithErrorResult = ['UQ13nr6urIo', 'hxa_Z0eZ83E', 'IWEHeIdBkc4'];
var callback = function() {
console.log("done");
console.log(tracks);
};
var requests = [], tracks = [];
for(i = 0; i < list.length; i++) {
requests.push($.ajax({
url: 'http://www.youtubeinmp3.com/fetch/?format=JSON&video=https://www.youtube.com/watch?v='+list[i],
dataType: "json",
success: function(data) {
console.log('suc');
tracks.push(data);
},error: function() {
console.log('err');
tracks.push('err');
}
}));
}
$.when.apply(undefined, requests).then(function(results){callback()});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
您可以将 .then()
句柄附加到您的 ajax 调用并确保每个 ajax 调用都得到解决而不是拒绝。这将在最后为您提供一组结果,保证包含您所有的 ajax 调用。:
var callback = function(/* tracks are passed here as arguments */) {
console.log("done");
var tracks = Array.prototype.slice.call(arguments);
console.log(tracks);
};
var requests = [];
for(var i = 0; i < list.length; i++) {
requests.push($.ajax({
url: 'http://www.youtubeinmp3.com/fetch/?format=JSON&video=https://www.youtube.com/watch?v='+list[i],
dataType: "json",
}).then(function(data) {
return data;
}, function(err) {
// convert failure into success so $.when() doesn't stop
return $.Deferred().resolve('err');
}));
}
$.when.apply($, requests).then(callback);
您还可以使用我编写的 $.settle()
版本,它让所有承诺完成并为您提供所有结果,即使有些承诺被拒绝。
您可以使用这个新函数 $.settle()
而不是 $.when()
(在第一个被拒绝的承诺处停止),它 returns 您可以得到所有承诺的结果。它 returns 一组 PromiseInspection 对象,允许您查询每个承诺的已解决值或拒绝原因。
你使用 $.settle()
就像 $.when()
一样,除了它 returns 所有结果都在 PromiseInspection 对象中并且它总是解析(从不拒绝)。由于 jQuery 将多个参数传递给 .then()
处理程序(特别是 Ajax 调用)的非标准方式,如果 .settle()
检测到多个参数,它会将它们复制到一个数组中所以从成功的 ajax 调用返回的 PromiseInspection.value 是一个数组 [data, textStatus, jqXHR]
。这是 jQuery 非标准承诺中最糟糕的部分。大概这是 jQuery 3.x 中的 fixed/changed ,它应该符合标准。此代码将适用于任何一种,因为它会自动检测 .then()
处理程序是否发送了多个参数并将它们转换为单个数组参数。
// ES6 version of settle
jQuery.settle = function(promises) {
function PromiseInspection(fulfilled, val) {
return {
isFulfilled: function() {
return fulfilled;
}, isRejected: function() {
return !fulfilled;
}, isPending: function() {
// PromiseInspection objects created here are never pending
return false;
}, value: function() {
if (!fulfilled) {
throw new Error("Can't call .value() on a promise that is not fulfilled");
}
return val;
}, reason: function() {
if (fulfilled) {
throw new Error("Can't call .reason() on a promise that is fulfilled");
}
return val;
}
};
}
return $.when.apply($, promises.map(function(p) {
return p.then(function(val) {
if (arguments.length > 1) {
val = Array.prototype.slice.call(arguments);
}
return new PromiseInspection(true, val);
}, function(err) {
if (arguments.length > 1) {
err = Array.prototype.slice.call(arguments);
}
return new PromiseInspection(false, err);
});
}));
}
您还必须向 $.when.apply
then
添加错误回调,因为它是其中一个调用失败时的错误条件。
$.when.apply(undefined, requests).then(
function(results){callback()},
function(results){callback()}
);
工作 jsBin here