等待异步函数返回一个范围对象

时间:2017-07-26 22:25:05

标签: office-js scriptlab

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

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

在学习了几个小时的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();
            });
    });
}

正如您所看到的,现在函数返回Promise,因为它(我认为)是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的对象怎么办?"

感谢您的示例和答案!

1 个答案:

答案 0 :(得分:2)

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

根据OP的评论编辑并重写问题:

请转到this sample并查看home.js文件中的getDocumentFilePath功能。构建类似它的getCurrentRangeSelection方法,并将上下文对象作为参数传递给它。然后使用上下文对象通过context.workbook.getSelectedRange()方法获取当前选定的范围。然后将要返回的内容(我假设当前选择的范围)作为resolve方法的参数传递。