有许多线程讨论如何保证循环中promises的执行顺序.我想知道Office API加载项JavaScript API的最佳实践.大多数情况下,有问题的承诺是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);
}
});
});
}
UPDATE
根据评论,如果您最终需要执行彼此依赖的单独任务,并且每个任务都需要往返,因此需要通过链接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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。