简体   繁体   English

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

[英]Return a value from a Javascript closure function?

I'm having trouble returning a value from a closure function in Javascript. 我在Javascript中从闭包函数返回值时遇到问题。 Originally I had a return statement in the inside function, but that didn't seem to work. 最初我在内部函数中有一个return语句,但这似乎不起作用。 I moved the return statement to the outer function, and it still returns undefined. 我将return语句移动到外部函数,它仍然返回undefined。 Shouldn't returnVal be given a value in the inner function before being returned in the outer function? 在外部函数返回之前,不应该在内部函数中给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;
};

Any help would be greatly appreciated! 任何帮助将不胜感激!

EDIT: moved the return statement 编辑:移动了返回语句

You can't do a "non-local return" in Javascript, where an inner function returns to an outer function. 您不能在Javascript中执行“非本地返回”,其中内部函数返回外部函数。

That said, your problem here is not the closures, its that you need to code your control flow using the promises. 也就是说,你的问题不在于闭包,而是你需要使用promises来编写控制流。 Javascript doesn't "pause" the current function if it emits an async request (like C# or Python would if you do a yield statement) and instead just keeps trucking on. 如果Javascript发出异步请求(如果你做一个yield语句就像C#或Python那样),Javascript不会“暂停”当前函数,而只是保持卡车运输。 This means that you are calling code to start an async request but going on and returning undefined before the request is complete. 这意味着您正在调用代码来启动异步请求,但在请求完成之前继续并返回undefined。 What you want to do, is instead immediately return a promise (instead of returning undefined) and do all your control flow inside the promise event handler, using promise-specific methods. 您想要做的是立即返回一个promise(而不是返回undefined)并使用promise特定方法在promise事件处理程序中执行所有控制流。 (It kind of sucks that you can't use return and for loops as usual but that is a Javascript wart you will have to live with until everyone starts using ES6 generators) (有点糟糕,你不能像往常一样使用returnfor循环,但这是一个Javascript wart,你将不得不忍受,直到每个人都开始使用ES6生成器)

First of all, getColumn should return a promise containing the value of the column. 首先, getColumn应返回包含列值的promise。 Right now, it does some computation but doesn's return anything: 现在,它做了一些计算,但没有返回任何东西:

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

Secondly, you usually can't just put async code inside a loop like that. 其次,你通常不能把异步代码放在这样的循环中。 First you need to choose if you want to do the requests in sequence (get the first header, when its done get the second header, etc) or if you want to fire all the header requests ar once and wait for the results. 首先,您需要选择是否要按顺序执行请求(获取第一个标头,完成第二个标头时等),或者如果要激活所有标头请求一次并等待结果。 These will have to be coded differently and how you write them will depend if you have to dcode everything by hand and what helper lib you are using for the promises. 这些必须以不同的方式编码,你如何编写它们将取决于你是否必须手工编码所有东西以及你正在使用什么帮助lib来实现承诺。

For example, if you want to do the processing sequentially, one way is to use recursion instead of a for loop. 例如,如果要按顺序执行处理,一种方法是使用递归而不是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);
});

The code for firing the requests in parallel will vary slightly depending on what promise library you are using. 并行触发请求的代码会略有不同,具体取决于您使用的promise库。 Hopefully you should have some sort of library function for doing that. 希望你应该有一些库函数来做到这一点。

Your logic is correct, you can return a value from an inner function to an outer function and then return that value from the outer function. 你的逻辑是正确的,你可以从内部函数返回一个值到外部函数,然后从外部函数返回该值。 This much simplified example derived from your code shows this: 从您的代码派生的这个简化示例显示了这一点:

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

function getColumn() {

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

  return returnVal;
};

This results in the following message in the console: 这会在控制台中产生以下消息:

Returned: test 退回:测试

The problem is that you are returning from the function passed to when() but not from the function that this itself is inside 问题是你从传递给when()的函数返回,而不是从它本身所在的函数返回

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM