我正在修改几年前由其他人构建的 Web 应用程序。在其中,他用 JS 构建了一个 API 函数,调用该函数时将从 SharePoint 中提取数据。我正在向应用程序添加一项功能,并且需要执行另一个 API 调用来检索一些不同的数据。到目前为止,我还没能弄清楚如何修改代码以使其等待ajax调用完成。我所做的所有研究都表明我应该使用回调来完成此任务,但我不确定如何正确实现它。
现有代码如下所示:
API = function(apiFunction, dataToPost, successCallback) {
var baseApiUrl = '/SomeWebApp/API/';
var apiUrl = baseApiUrl + apiFunction;
$.ajax({
url: apiUrl,
data: JSON.stringify(dataToPost),
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function(data) { return data; },
success: successCallback,
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('Error calling webservice: ' + apiFunction);
}
});
}
对API的调用是:
API('Lists.asmx/GetStuff', dataToPost, function(data) {
var options = [];
$.each(data.d, function(index, value) {
options.push(new Category(value.Field, value.AnotherField, value.YetAnotherField));
});
var viewModel = new ViewModel(options);
ko.applyBindings(viewModel);
});
我需要做的是执行第二个 API 调用来检索其余数据,然后创建 View 模型,并向其传递两组数据。
我尝试过的:
将
options
移到回调函数之外,但似乎因为它是异步的,所以脚本不会等待返回数据。如果它确实有效,我可以将 ko.ApplyBindings 移到回调函数之外,然后使用两组数据创建新的 View 模型将 API 调用分配给变量,并让回调函数返回
选项
。例如:var x = API('Lists.asmx/GetStuff', dataToPost, function(data) { var options = []; $.each(data.d, function(index, value) { options.push(new Category(value.Field, value.AnotherField, value.YetAnotherField)); }); return options; });
修改代码以实现此目的的最佳方法是什么?我应该创建一个包含 API 函数作为回调的包装函数吗?我该如何将它们组合在一起?
最佳答案
快速但肮脏的解决方案是将第二个 API 调用放在第一个 API 调用的回调函数中。 Return 语句实际上不会在异步函数中执行任何操作,除非它返回“promise”(请参阅选项 2)。
API('Lists.asmx/GetStuff', dataToPost, function(data) {
var options = [];
$.each(data.d, function(index, value) {
options.push(new Category(value.Field, value.AnotherField, value.YetAnotherField));
});
API('Lists/asmx/GetStuff2', secondDataToPost, function(data2){
var viewModel = new ViewModel(options, data2);
ko.applyBindings(viewModel);
});
});
选项 2 - 由于您的 API 函数已经使用 jQuery 来处理 ajax,您可以将其更改为返回 ajax 调用的结果(一种延迟对象类型),您可以在其上调用 .done 来附加回调方法。 jquery-deferred-and-promise walkthrough
API = function(apiFunction, dataToPost, successCallback) {
var baseApiUrl = '/SomeWebApp/API/';
var apiUrl = baseApiUrl + apiFunction;
return $.ajax({
...
});
}
返回的延迟对象可以与传入的回调类似地使用该对象的 .done 方法。
API('Lists.asmx/GetStuff', dataToPost).done(function(data) {
callback stuff...
});
这更加灵活,可以让您进行链接和同时执行,如下所示,两个 api 调用同时发送,而不必在发送第二个调用之前等待第一个调用的响应。
$.when(
API('Lists.asmx/GetStuff', dataToPost),
API('Lists.asmx/GetStuff2', dataToPost2)
).done(function(data1, data2) {
var options = [];
$.each(data.d, function(index, value) {
options.push(new Category(value.Field, value.AnotherField, value.YetAnotherField));
});
var viewModel = new ViewModel(options, data2);
ko.applyBindings(viewModel);
});
关于javascript - 如何修改JS代码以复用API调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537599/