You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SharePoint 2013中Promise处理REST更新后HTML重载问题

Promise实际运用问题:SharePoint更新后渲染旧数据的解决方案

问题描述

我自认为理解Promise,但实际运用仍有困惑。我基于SharePoint 2013开发了一款应用,通过sprLib发起REST请求填充数据对象,支持完整的CRUD操作(新增、删除、更新条目),并能将变更同步回列表,这部分功能目前运行正常。现在我希望在执行更新操作后,先清空div标签,再调用初始加载函数重新渲染最新的列表数据,但目前要么出现Promise语法错误,要么因竞态条件导致初始加载函数在更新完成前就执行,最终渲染的仍是旧列表。我制作了一个简化版本模拟该场景(未包含REST更新逻辑):

简化场景代码

JavaScript代码

const fullList = [                             // 真实环境中通过REST接口填充
    { id: "12", title: "A", code: "110" },
    { id: "23", title: "B", code: "120" },
    { id: "13", title: "C", code: "130" },
    { id: "43", title: "D", code: "140" },
    { id: "52", title: "E", code: "150" },
]

$(document).ready(function () {
    initialLoad(fullList);

    $('#updateList').click(function() {
        let item = $('#txtValue').val();
        addToList(item).then(function(result){
            console.log('add complete');
            initialLoad(fullList);
            console.log('reloaded');
        })
        .catch(function(){
            console.log('fail');
        })
    });
})

function initialLoad(list) {
    // 真实环境中是用sprLib执行getItem操作
    $('#itemList').empty();
    let listHTML = ''
    for (i = 0; i < list.length; i++) {
        listHTML += '<p>'+list[i].title+' ' +list[i].code+'</p>'
    }
    $('#itemList').append(listHTML);
}

function addToList(entry) {
    return new Promise(function(resolve, reject) {
        console.log('I go first');
        fullList.push({ 'id': "", 'title': entry, 'code': ""}); // 真实环境中是用sprLib执行CRUD操作
        setTimeout(() => resolve("done"), 5000);
    });
}

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise</title>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript"></script>    
    <script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js" type="text/javascript"></script>
    <script src="/scripts/promise.js"></script>
    <link href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/select/1.4.0/css/select.dataTables.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">

</head>
<body><br><br>
    <div class="container text-center row">
        
        <div class="card col-2 bg-primary text-light" id="itemList">
        
        </div>
        
        <div class="card col-2 bg-secondary"><input type="text" class="form" id="txtValue">
        <button type="button" class="btn btn-success" id="updateList">Submit</button></div>
    
    </div>
</body>
</html>

解决方案

你的简化代码逻辑本身是正确的,但实际SharePoint场景中出现问题,核心原因通常是没有正确等待sprLib的异步操作完成,或者依赖内存中的数据而非重新拉取最新数据。以下是针对性解决办法:

1. 改用async/await简化Promise逻辑

链式then/catch容易出现语法错误,改用async/await能让异步代码的执行顺序更直观,降低出错概率。

2. 避免依赖内存数据,重新拉取最新数据

实际场景中不要依赖全局的fullList,每次渲染前通过sprLib重新获取列表数据,彻底避免内存数据与SharePoint列表不一致的问题。

修正后的实际场景代码

$(document).ready(function () {
    // 初始加载最新数据
    loadListData();

    $('#updateList').click(async function() {
        let item = $('#txtValue').val();
        try {
            // 等待sprLib新增操作完全完成
            await addToList(item);
            console.log('新增完成');
            // 重新加载并渲染最新数据
            await loadListData();
            console.log('重新加载完成');
        } catch (error) {
            console.error('操作失败:', error);
        }
    });
})

// 封装加载数据函数:清空div → 拉取最新数据 → 渲染
async function loadListData() {
    $('#itemList').empty();
    // 通过sprLib获取SharePoint列表最新数据
    const latestItems = await sprLib.list('你的列表名称').items().get();
    
    let listHTML = '';
    for (const item of latestItems) {
        listHTML += `<p>${item.Title} ${item.Code}</p>`;
    }
    $('#itemList').append(listHTML);
}

// 封装新增操作:返回sprLib的Promise对象
async function addToList(entry) {
    // sprLib的create方法默认返回Promise,直接返回即可
    return await sprLib.list('你的列表名称').create({
        Title: entry,
        Code: ''
    });
}

关键说明

  • 确保异步操作顺序:通过await保证新增操作完全完成后,再执行数据拉取和渲染,彻底解决竞态条件问题。
  • 数据来源可靠:每次渲染都从SharePoint拉取最新数据,避免内存数据过期导致的旧数据渲染。
  • 代码可读性提升:async/await替代链式then/catch,逻辑更清晰,减少语法错误概率。

内容的提问来源于stack exchange,提问作者Eric Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:54:24