javascript - 遍历 ajax 调用的最佳方法是什么

标签 javascript jquery ajax promise deferred

我正在使用 Sharepoint,并且我有一个在网站集中创建列表的应用程序(不是应用程序!)。创建列表不是问题。 我不想创建 15 列并将它们添加到默认 View 。我准备了一个包含列表及其字段信息的“配置”。

var ChangeRequestLogListConfig = {
    listName: 'ChangeRequestLog',
    fields: [
        { 'FieldTypeKind': 8, 'Title': 'STC Relevant', 'InternalName': 'STCrelevant', 'StaticName': 'STCrelevant' },
        { 'FieldTypeKind': 3, 'Title': 'Description/Reason', 'InternalName': 'DescriptionReason', 'StaticName': 'DescriptionReason' },
        { 'FieldTypeKind': 6, 'Title': 'Source of Change', 'InternalName': 'SourceOfChange', 'StaticName': 'SourceOfChange', 'Choices': { 'results': ['customer', 'internal'] } },
        //12 more objects like the above
    ]
}

我们遇到了问题:使用其余资源 .../ViewFields/AddViewField.../fields(使用 http post 创建新资源)仅支持一个参数,这意味着我必须进行 2x15 次 ajax 调用。

执行所有这 30 个操作然后执行最终回调的正确方法是什么?我当然知道如何遍历字段数组,只是不知道如何以正确的方式构建最终回调。

更新/跟进

在一些答案的帮助下,我设法构建了以下代码:

var spExecutor = new SP.RequestExecutor(_spPageContextInfo.siteAbsoluteUrl);
var requestUrl = _spPageContextInfo.siteAbsoluteUrl + "/_api/SP.AppContextSite(@target)/web/Lists/getbytitle('" + listConfig.listName + "')/fields?@target='" + hostWebUrl + "'";

//map field configs to promises
var promises = listConfig.fields.map(fieldConfig => {
    return spExecutor.executeAsync({
        url: requestUrl,
        method: "POST",
        body: JSON.stringify(fieldConfig),
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json; odata=verbose"
        },
        error: err => console.log(err)
    });
});

//Wait for all calls to be done
$.when.apply($, promises).then(callbackFn);

您可能已经看到,我没有使用 $.ajax,而是使用 SP.RequestExecutor。 问题:这不会像 jQuery 的 ajax 那样返回 promise 。这会导致计时问题(--> 15 Calls at once,浏览器大多只支持 4 个并行调用)。上面的代码有效,如果我设置断点并在调用之间等待 1-2 秒,它会按预期创建所有字段。

我的后续问题:如何等待第一次调用 init 完成,然后是第二次,然后是第三次等等? 我不确定我是否以正确的方式使用了 promises。

最佳答案

使用.map将每个字段转换为Promise:

var promises = ChangeRequestLogListConfig.fields.map(
    item => $.ajax( ... )
);

然后 $.when 等待它们全部完成:

$.when.apply($, promises).then( ... );

请注意,这将在您的浏览器允许的情况下并行启动尽可能多的 AJAX 请求 - 通常是四个。

编辑 既然您说过您实际上希望 AJAX 查询连续运行(以避免服务器 409 错误),我的 addFieldsToList 函数版本将如下所示:

function addFieldsToList(listConfig) {

    return listConfig.fields.reduce(function(promise, field) {
        return promise.then(executeRequest(field, listConfig.listName));
    }, Promise.resolve(null));

}

避免传递回调,因为此函数的返回值本身就是一个您可以链接的 Promise:

addFieldsToList(myConfig).then(callback);

关于javascript - 遍历 ajax 调用的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39979424/

相关文章:

javascript - Ajax 返回空白响应

ajax - 如何在 ajax update/process/render/execute 中引用#{cc.clientId}?

php - AJAX 请求根据 ID 删除列。

javascript - 即使没有点击也会触发 onclick 事件

javascript - 将 CoffeeScript 编译为特定的 Javascript 文件

c# - 使用 MVC 5 从 SignalR 中的 Controller 调用 Javascript 方法

jquery - 在悬停 img 上显示 div

javascript - 无法访问 __proto__ 上的 Getter 方法

php - 它没有在数据库中插入正确的值?

javascript - 如何延迟 .keyup() 处理程序直到用户停止键入?