javascript - 如何修改JS代码以复用API调用?

标签 javascript api knockout.js

我正在修改几年前由其他人构建的 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/

相关文章:

javascript - 有没有办法在不先声明数据参数的情况下访问 knockout 按键绑定(bind)中的第二个事件参数?

javascript - 如何在 Redux 中更新状态后触发关闭回调?

iphone - 按大小压缩图像 - iPhone SDK

javascript - 如何在 knockout.js 中检查值是否为 NULL 或未分配?

javascript - 当我点击浏览器上的“查看源代码”时,无法查看 Html

web-services - Foursquare 现在的商品掉了吗?

javascript - 在 Javascript 中创建子类时,为什么要分配原型(prototype)字段?

javascript - 在数组中获取高于平均值的值 - JS

javascript - 如何使用 ajax 将与每个按钮相关的数据发送到 php?

C# 获取鼠标句柄 (GetRawInputDeviceInfo)