You can't do a "non-local return" in Javascript, where an inner function returns to an outer function.
That said, your problem here is not the closures, its that you need to code your control flow using the 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. This means that you are calling code to start an async request but going on and returning undefined before the request is complete. 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. (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)
First of all, getColumn
should return a promise containing the value of the column. 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.
For example, if you want to do the processing sequentially, one way is to use recursion instead of a for loop.
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. Hopefully you should have some sort of library function for doing that.