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

问题描述:

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


编辑1 - 里克Kirkham的:我已经简化了代码,所以现在有可能只是把它粘贴在默认基本API调用(JavaScript的)模板ScriptLab进行测试。

学习承诺为小时后,我想我接近我想要的东西,但它仍然不能正常工作:

$("#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函数的返回值,现在我将期望的返回范围作为参数传递,但仍然不起作用。 更多提示?


EDIT 2 - 里克Kirkham的

(1)我试图创建一个返回无极的功能,这样我就可以在来电者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对象”

感谢您的例子和答案!

+0

仅供参考,第一个代码的部分问题是您有效地执行了两个不同的'Excel.run'-s。当你这样做的时候事情会变得非常混乱。我最近在[我的书](https:// leanpub)中增加了一个很长的部分。com/buildingofficeaddins),“在线性”Excel.run或Word.run流程外使用对象(例如,在按钮单击回调中,在setInterval等中)“。然而,这种情况并不适用于你,因为你试图获得线性流量,如果它是线性流量,那么一个“Excel.run”就足够了。希望这是有道理的。 –

+0

我不确定你是否仍然有问题,或者是否所有的东西都已经被Ricky回答 - 但如果你仍然这样做,只需在单独的*线程上询问它。 –

+0

一切都回答了,谢谢你的评论和是的,我读了你的书关于这部分,并最终抓住了这个概念! –

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

编辑在下面的OP的意见光,改写问题:

请到this sample并查看home.js文件getDocumentFilePath功能。像你一样构造getCurrentRangeSelection方法,并将上下文对象作为参数传递给它。然后使用上下文对象通过context.workbook.getSelectedRange()方法获取当前选定的范围。然后将想要返回的事物(当前选定的范围,我推测)作为参数传递给resolve方法。

+0

谢谢,但我不知道该怎么做。任何参考? –

+0

Just Bing“JavaScript Promises”,你会得到很多点击,包括初学者的指南和教程。 –

+0

感谢您的提示,但它仍然无法正常工作。你能看到编辑的注意事项吗? –