我正在开发一个客户端 JS 应用程序,该应用程序应该读取 CSV 文件,每行进行一些 API 调用,然后将结果写回 CSV。我所关注的部分是如何编排请求并在所有完成后触发一个函数。这是我到目前为止所拥有的:
var requests = [];
// loop through rows
addresses.forEach(function (address, i) {
// make request
var addressRequest = $.ajax({
dataType: 'json',
url: 'http://api.com/addresses/' + address,
success: function (data, textStatus, jqXhr) { APP.didGetAddressJson(data, i, jqXhr) },
error: function (jqXhr, textStatus, errorThrown) { APP.didFailToGetAddressJson(errorThrown, i) },
});
requests.push(addressRequest);
// make some more requests (handled by other success functions)
});
// leggo
$.when.apply($, requests).done(APP.didFinishGeocoding);
问题是,如果其中一行抛出 404done
函数未被调用。我把它切换到always
现在它被调用,但不是在最后——如果我将每个回调的执行记录到控制台,它通常在中间的某个地方。但是,如果我编辑 CSV,那么就不会出现错误,它会按预期在最后被调用。我在这里做的事情是否允许always
早点开火?
Update:难道只是控制台正在记录它出故障?
您需要防止发送返回的承诺时出现错误$.when.apply($, requests)
沿着错误路径。
这可以通过以下方式实现:
- 链接
.then()
给你的$.ajax()
调用,而不是指定“成功”和“错误”处理程序$.ajax()
选项。
- 通过转换为成功来处理错误(因为这是 jQuery,您必须从错误处理程序返回已解决的承诺)。
这种方法还允许您控制最终传送到的数据APP.didFinishGeocoding()
通过一些假设,代码的一般形式应如下所示:
function foo () {//assume there's an outer function wrapper
var errorMarker = '**error**';
var requests = addresses.map(function (address, i) {
return $.ajax({
dataType: 'json',
url: 'http://api.com/addresses/' + address
}).then(function (data, textStatus, jqXhr) { //success handler
return APP.didGetAddressJson(data, i, jqXhr); //whatever APP.didGetAddressJson() returns will appear as a result at the next stage.
}, function (jqXhr, textStatus, errorThrown) { // error handler
APP.didFailToGetAddressJson(errorThrown, i);
return $.when(errorMarker);//errorMarker will appear as a result at the next stage - but can be filtered out.
});
// make some more requests (handled by other success functions)
});
return $.when.apply($, requests).then(function() {
//first, convert arguments to an array and filter out the errors
var results = Array.prototype.slice.call(arguments).filter(function(r) {
return r !== errorMarker;
});
//then call APP.didFinishGeocoding() with the filtered results as individual arguments.
return APP.didFinishGeocoding.apply(APP, results);
//alternatively, call APP.didFinishGeocoding() with the filtered results as an array.
//return APP.didFinishGeocoding(results);
});
}
根据需要进行调整。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)