gpt4 book ai didi

excel - 在 Office.js 中使用 Excel.run() 链接 Promise

转载 作者:行者123 更新时间:2023-12-02 09:28:54 25 4
gpt4 key购买 nike

我正在使用新的office.js。我正在使用返回 promise 的 Excel.run 功能。我对库实现的 promise 模式有疑问。

样本都显示出这种模式

Excel.run( function (ctx) {

//set up something

return ctx.sync().then (function () {
//call another function somewhere to chain operations
});

}).then ( function () {
//do something else if you want
}).catch (function (error) {
handle errors
});

问题是 Excel.run() 中包含的 ctx.sync().then()从它的呈现方式来看,您无法按照 Promise 规范链接 Promise,因为如果您尝试在 Excel.run() 之外处理 then(),则会丢失上下文对象因此,该模式似乎正在促进嵌套函数调用,而这正是 Promise 应该消除的。

我想要做的是通过像这样的链接将多个调用排序在一起:

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

});

这可能吗?

最佳答案

一般来说,Excel.run 的目的是针对 OM 进行顺序操作,并在最后自动清理。也就是说,Excel.run 创建一个上下文,运行您的操作,然后清除已分配的所有主机对象。

话虽这么说,正如 Gab Royer 提到的,您可以将对象传递出去。此外,每个 Excel 对象都有一个通过“.context”属性指向其“上下文”的反向指针。例如,您可以这样做:

Excel.run(function (ctx) {
var worksheet = ctx.workbook.worksheets.getActiveWorksheet();
return ctx.sync(worksheet);
}).then(function(worksheet) {
worksheet.name = "Test"
return worksheet.context.sync();
}).catch(function(e) {
console.log(e)
});

如您所见,在上面的代码中,您已在 Excel.run 内创建了工作表对象,但在外部使用它。

如果你有像 Range 对象这样的东西,它会变得有点棘手。与工作表不同,区域没有具有持久 ID(它们怎么可能?本质上存在无数种可能的单元格组合的排列)。相反,在 Excel.run 期间,我们会自动创建指向由 Excel 调整和跟踪的支持 Range 对象的持久指针。当Excel.run内部的批处理完成时,我们告诉主机销毁这些引用。因此,如果您有这样的代码:

Excel.run(function (ctx) {
var range = ctx.workbook.getSelectedRange();
return ctx.sync(range);
}).then(function(range) {
range.format.fill.color = "red";
return ctx.sync();
}).catch(function(e) {
console.log(e)
})

它将遇到“InvalidObjectPath”错误。

但是,您可以通过手动将对象添加到 ctx.trackedObjects 集合中来选择退出跟踪对象清理。然而,在这样做时,你要自己承担起最后的清理工作——而且你需要格外小心,记住不仅在成功时清理,而且在失败时清理。否则,您实际上会造成内存泄漏,从而不断减慢 Excel 主机应用程序的速度。

var range;
Excel.run(function (ctx) {
range = ctx.workbook.getSelectedRange();
ctx.trackedObjects.add(range);
return ctx.sync(range);
}).then(function(range) {
range.format.fill.color = "red";
return range.context.sync();
}).then(function() {
// Attempt to clean up any orphaned references
range.context.trackedObjects.remove(range);
range.context.sync(); // don't need to await it, since it's just the final cleanup call
}).catch(function(e) {
console.log(e);
})

长话短说:这当然是可行的,并且您可以在 Excel.run 之后使用对象。您只需要负责任何需要“跟踪”的对象的内存管理。在上面的示例中,没有理由要完成这项工作,因为您也可以在 Excel.run 中使用相同的代码(记住,您可以在<内链接 promise )/em> Excel.run 内部的批处理——无需在外部执行此操作)。但是,如果您有一个场景,比如说,您有一个需要经常运行的计时器作业(例如,更新股票行情),或者您想要为特定对象创建一个带有 onclick 处理程序的按钮,等等.上面的技术将让您在 Excel.run 内部创建对象,然后在其外部使用它们。

PS:关于需要嵌套的模式:确实,如果您需要在 Excel.run 中链接 ctx.sync() 调用,您将结束一层嵌套——但只是一个额外的层。在内部,您仍然可以在没有回调金字塔的情况下链接您的 promise 。例如:

Excel.run(function (ctx) {
var range = ctx.workbook.worksheets.getActiveWorksheet().getRange("A1:C3");
range.load("values");
return ctx.sync()
.then(function () {
// Some set of actions against the OM, now that the "values"
// property has been loaded and can be read from the "range" object.
})
.then(ctx.sync)
.then(function () {
// Another set of actions against the OM, presumably after doing
// another load-requiring operation (otherwise could have
// been part of the same .then as above)
})
.then(ctx.sync)
.then(function() {
// One final set of actions
});
}).catch(function(error) {
console.log("Error: " + error);
});

关于excel - 在 Office.js 中使用 Excel.run() 链接 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32786589/

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