0

我想使用一个函数来返回一个范围对象,但是因为该函数是异步的,所以当我的代码到达时currentRangeSelection.select();,它仍然是null. 如何强制代码等待函数getCurrentRangeSelection,以便我可以获取对象undefined


编辑 1 - Rick Kirkham:我已经简化了代码,所以现在可以将其粘贴到 ScriptLab 中的默认基本 API 调用 (JavaScript)模板中进行测试。

在研究了几个小时的 Promises 之后,我想我已经接近了我想要的,但它仍然不起作用:

$("#run").click(run);

function run() {
    var currentRangeSelection;

    return Excel.run(function (context) {
        return context.sync()
            .then(function () {
                return getCurrentRangeSelection(currentRangeSelection)
            })
            .then(function () {
                // this returns an error because currentRangeSelection is undefined:
                console.log("Outside the function: " + currentRangeSelection.address);
                currentRangeSelection.select();
                return context.sync();
            })
    })
        .catch(function (error) {
            console.log(error);
        });
}

function getCurrentRangeSelection(rangeSelection) {
    return Excel.run(function (context) {
        return context.sync()
            .then(function () {
                rangeSelection = context.workbook.getSelectedRange();
                rangeSelection.load();
                return context.sync();
            })
            .then(function () {
                // this works:
                console.log("Inside the function: " + rangeSelection.address);
                return context.sync();
            });
    });
}

如您所见,现在函数返回 aPromise因为它(我认为)是Excel.run函数的返回值,现在我将所需的返回范围作为参数传递,但仍然不起作用。还有什么提示吗?


编辑 2 - Rick Kirkham

(1) 我试图创建一个返回 Promise 的函数,所以我可以将它插入到调用者then链中。因此,我唯一的选择是将返回范围的参数作为引用传递。

(2) 是的,我同意你的看法。我认为 (1) 解释了为什么我没有首先返回范围对象。

(3) 是的,我解决了这个问题。

(4) 原始函数更复杂,Office-JS API 中的单个方法不会返回我真正想要的。我通过这样做解决了我的问题:

$("#run").click(run);

function run() {
    var testRange;

    return Excel.run(function (context) {
        return context.sync()
            .then(function () {
                testRange = getCurrentRangeSelection(context);
                testRange.load();
                return context.sync();
            })
            .then(function () {
                console.log(testRange.address); // this works
                return context.sync();
            });
    }).catch(function (error) {
        console.log(error);
    });
}


function getCurrentRangeSelection(context) {
    var rangeSelection = context.workbook.getSelectedRange();
    var activeWorksheet = context.workbook.worksheets.getActiveWorksheet();
    var usedRange = activeWorksheet.getUsedRange();
    return usedRange.getIntersection(rangeSelection);
}

我在编辑时回答的下一个问题是:“如果我希望函数getCurrentRangeSelection返回一个已经存在的loaded对象怎么办?”

感谢您的示例和答案!

4

1 回答 1

2

试试这个:重新设计getCurrentRangeSelection函数以返回一个 Promise 对象。然后调用thenpromise对象的方法来调用currentRangeSelection.select()

根据以下 OP 的评论和重写的问题进行编辑:

请转到此示例并查看getDocumentFilePathhome.js 文件中的函数。像它一样构造你的getCurrentRangeSelection方法,并将上下文对象作为参数传递给它。然后使用上下文对象用方法获取当前选中的范围context.workbook.getSelectedRange()。然后将要返回的东西(我想是当前选择的范围)作为参数传递给resolve方法。

于 2017-07-27T19:46:01.673 回答