从Javascript闭包函数返回一个值?

时间:2014-04-02 19:28:06

标签: javascript angularjs function protractor

我在Javascript中从闭包函数返回值时遇到问题。最初我在内部函数中有一个return语句,但这似乎没有用。我将return语句移动到外部函数,它仍然返回undefined。在外部函数返回之前,不应该在内部函数中给returnVal一个值吗?

console.log('Returned: ' + getColumn('CPC'));

function getColumn(header) {
  var returnVal = undefined;

  ptor.findElements(protractor.By.className('ngHeaderText')).then(function(headers) {

    for (var i = 0; i < headers.length; i++) {
      (function(i){
        headers[i].getText().then(function(headerResult) {
          if (headerResult == header) {
            console.log('i: ' + i);
            returnVal = i;
          }
        });
      })(i);
    }
  });

  return returnVal;
};

非常感谢任何帮助!

编辑:移动了返回语句

2 个答案:

答案 0 :(得分:2)

您无法进行非本地回复&#34;在Javascript中,内部函数返回外部函数。

那就是说,你的问题不在于闭包,而是你需要使用promises来编码你的控制流。 Javascript没有&#34;暂停&#34;当前函数,如果它发出一个异步请求(比如C#或Python,如果你做一个yield语句),而只是继续卡车运行。这意味着您正在调用代码来启动异步请求,但在请求完成之前继续并返回undefined。您想要做的是立即返回一个promise(而不是返回undefined)并使用promise特定方法在promise事件处理程序中执行所有控制流。 (有点像往常一样,你不能像往常一样使用returnfor循环,但这是一个Javascript疣,你必须忍受,直到每个人都开始使用ES6生成器)

首先,getColumn应返回包含列值的promise。现在,它做了一些计算,但没有返回任何东西:

function getColumn(header){
     return ptro.findElements(...);
   // ^^^^^ 
}

其次,您通常不能将异步代码放在这样的循环中。首先,您需要选择是否要按顺序执行请求(获取第一个标头,完成第二个标头时等),或者如果要激活所有标头请求一次并等待结果。这些必须以不同的方式编码,你如何编写它们将取决于你是否需要手动编码所有内容以及你用于承诺的帮助程序库。

例如,如果要按顺序执行处理,一种方法是使用递归而不是for循环。

then(function(headers) {

    function loop(i){
        if( i >= headers.length) {
            return null; //not found
        }else{
            return headers[i].getText().then(function(headerResult) {
                if (headerResult == header) {
                    console.log('i: ' + i);
                    return i;
                }else{
                    return loop(i+1);
                }
             });
         }
     }

     return loop(0);
});

并行触发请求的代码会略有不同,具体取决于您使用的promise库。希望你有这样的库函数。

答案 1 :(得分:0)

您的逻辑是正确的,您可以将一个值从内部函数返回到外部函数,然后从外部函数返回该值。从您的代码派生的这个简化的示例显示了这一点:

console.log('Returned: ' + getColumn());

function getColumn() {

  var returnVal = undefined;
  (function(){
      returnVal = 'test';     
  })();  

  return returnVal;
};

这会在控制台中显示以下消息:

  

退回:测试

问题是你从传递给when()的函数返回而不是从它本身在里面的函数返回