gpt4 book ai didi

javascript - 在 JavaScript API for Office 中使用 promise (ctx.sync) 编写循环的最佳方式

转载 作者:行者123 更新时间:2023-11-29 16:49:07 24 4
gpt4 key购买 nike

有很多线程讨论保证循环中 promise 的执行顺序。我想知道 Office 加载项的 JavaScript API 的最佳实践是什么。大多数时候,有问题的 promise 是 ctx.sync()

这是一个片段,用于逐个打印 Excel 范围列表的地址。测试表明它很好地尊重 Excel 范围的顺序。但问题是是否以及如何保证执行顺序?

function loadAll () {
var ranges = ["A:A", "B:B", "C:C", "D:D", "E:E"];
var sheet = "Sheet1";
for (var i = 0; i < ranges.length; i++) {
loadRange(ranges[i], sheet);
}
}

function loadRange (range, sheet) {
Excel.run(function (ctx) {
var r = ctx.workbook.worksheets.getItem(sheet).getRange(range);
r.load('address');
return ctx.sync().then(function() {
console.log(r.address);
});
});
}

有人能帮忙吗?

最佳答案

因为 Excel.run 返回一个 Promise,您可以将它与 .then 链接起来并保证顺序。即,

Excel.run(function(ctx) { ... return ctx.sync(); ... })
.then(function() {
return Excel.run(function(ctx) { ... return ctx.sync(); ... })
})
.then(function() {
return Excel.run(function(ctx) { ... return ctx.sync(); ... })
});

话虽这么说……这会非常低效。一种更好的方法是批量加载您需要的所有对象,只创建一次网络往返(对于 Excel Online 尤其重要……但即使在桌面上也很明显):

function loadAll () {
Excel.run(function(ctx) {
var ranges = ["A:A", "B:B", "C:C", "D:D", "E:E"];
var sheet = "Sheet1";

var loadedRanges = [];
for (var i = 0; i < ranges.length; i++) {
var r = ctx.workbook.worksheets.getItem(sheet).getRange(ranges[i]);
r.load('address');
loadedRange.push(r);
}

return ctx.sync()
.then(function() {
for (var i = 0; i < loadedRanges.length; i++) {
console.log(loadedRanges[i].address);
}
});
});
}

更新

如果根据评论,您最终确实需要执行相互依赖且每个任务都需要往返的单独任务,因此确实需要通过链接 Excel.run 进行排序,我会推荐如下内容:

function loadAll () {
var ranges = ["A:A", "B:B", "C:C", "D:D", "E:E"];
var sheet = "Sheet1";

// Create a starter promise object
var promise = new OfficeExtension.Promise(function(resolve, reject) { resolve (null); });

for (var i = 0; i < ranges.length; i++) {
// Create a closure over i, since it's used inside a function that won't be immediately executed.
(function(i) {
// Chain the promise by appending to it:
promise = promise.then(function() {
return loadRange(ranges[i], sheet);
})
})(i);
}
}

function loadRange (range, sheet) {
return Excel.run(function (ctx) {
var r = ctx.workbook.worksheets.getItem(sheet).getRange(range);
r.load('address');
return ctx.sync().then(function() {
console.log(r.address);
});
});
}

~ Michael Zlatkovsky,Office Extensibility 团队开发人员,MSFT

关于javascript - 在 JavaScript API for Office 中使用 promise (ctx.sync) 编写循环的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37900233/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com