如何使用 JSOM 在 SharePoint 列表中插入超过 5000 个项目?

How to insert more than 5000 items in SharePoint list using JSOM?

我正在尝试使用 JSOM 在 SharePoint 列表中添加 5000 个项目。但不幸的是没有得到任何运气。

function createListItem() {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('DummyList');

    var itemCreateInfo = new SP.ListItemCreationInformation();
    for (var i = 0; i < 5000; i++) {
        this.oListItem = oList.addItem(itemCreateInfo);

        oListItem.set_item('ItemNumber', i);
        oListItem.update();
    }

    clientContext.load(oListItem);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {
    console.log('Item created: ' + oListItem.get_id());
}

function onQueryFailed(sender, args) {
    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

但是一段时间后服务器停止响应。我知道有一种叫做阈值限制的东西。但是根据要求一次只能存储5000个以上的项目。我不知道我在哪里犯了错误。请帮忙。

这是一个建议。它确实适用于我的环境。虽然这需要一些时间(大约 20 秒),因为所有请求都由服务器排队。您可能可以使用批处理限制来优化请求数量。

function createListItem() {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('DummyList');

    var items = [];
    var batchLimit = 100;

    for (var i = 0; i < 5000; i++) {
        var itemCreateInfo = new SP.ListItemCreationInformation();
        var newItem = oList.addItem(itemCreateInfo);

        newItem.set_item('ItemNumber', i);
        newItem.update();
        items[i] = newItem;
        clientContext.load(items[i]);

        if (i % batchLimit == 0) {
            console.log("sending batch" + i / batchLimit);                                
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
            items = [];
        }            
    }
}

function onQuerySucceeded() {
    console.log('Item created');
}

function onQueryFailed(sender, args) {
    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

我不知何故找到了解决方案。我没有使用回调方法,而是像这样使用 REST API

function RestAdd()
{

      for(var i = 0 ; i < 5000; i++)
      {
$.ajax  
    ({  
    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('DummyListForMultiAdd')/items",  
    type: "POST",
    async: false,
    data: JSON.stringify  
    ({  
        __metadata:  
        {  
            type: "SP.Data.DummyListForMultiAddListItem"  
        },  
        ItemNumber: i
    }),  
    headers:  
    {  
        "Accept": "application/json;odata=verbose",  
        "Content-Type": "application/json;odata=verbose",  
        "X-RequestDigest": $("#__REQUESTDIGEST").val(),  
        "X-HTTP-Method": "POST"  
    },  
    success: function(data, status, xhr)  
    { 
    console.log("success: "+i);
    },  
    error: function(xhr, status, error)  
    {  
        console.log("failed: "+i);
    }  
});
}
}

我所做的是,我只是将 REST API 与 async:false 一起使用。它以同步方式添加您的列表项。在 JSOM 中,它以异步方式工作。

这里是两种技术的结合。

async function createListItem() {
  const url = `${_spPageContextInfo.webAbsoluteUrl}/_api/web/lists/getbytitle('DummyListForMultiAdd')/items`;
  for (let index = 0; index < data.length; index += 100) {
    const finalNumber = index + 100 < data.length ? index + 100 : data.length;
    const batch = data.slice(index, finalNumber);
    const batchPromises = batch.map((d, i) => {
      d.__metadata = {
        type: "SP.Data.DummyListForMultiAddListItem"
      };
      d.ItemNumber = i + index;
      return xhr("post", url, d);
    })
    await Promise.all(batchPromises);
  }

  function xhr(type, url, data) {
    const prom = new Promise((res, rej) => {
      const xhr = new XMLHttpRequest();
      xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          try {
            if (xhr.status === 200 || xhr.status === 201) {
              res(xhr.responseText);
            } else {
              const {
                status
              } = xhr;
              const name = "XHRError";
              const message =
                xhr.responseText ||
                "An error occured in sending or recieving the request";
              throw {
                status,
                name,
                message
              };
            }
          } catch (error) {
            if (error.status) {
              rej(error);
            } else {
              rej({
                status: 418,
                name: error.name,
                message: error.message
              });
            }
          }
        }
      };
      xhr.open(type, url);
      [{
          key: "Accept",
          value: "application/json;odata=verbose"
        },
        {
          key: "Content-Type",
          value: "application/json;odata=verbose"
        },
        {
          key: "X-RequestDigest",
          value: document.querySelector("#__REQUESTDIGEST").value
        }
      ].forEach(h => xhr.setRequestHeader(h.key, h.value));
      xhr.send(JSON.stringify(data));
    });
    return prom;
  }
}
createListItem()