如何跟踪异步调用中的同步变量

时间:2016-08-22 06:56:27

标签: javascript asynchronous protractor

我正在使用量角器来运行e2e测试用例。所有量角器调用都是异步调用。以下代码是一个量角器代码:

 gridRow.then(function (rows) {
                for (var index = 0; index < rows.length; index++) {
                    console.log(index); -------------------- 1
                    rows[index].all(by.className('ui-grid-cell-contents ng-scope')).get(1).getText().then(function (text) {
                        console.log(index); ----------------- 2
                        if (text.toUpperCase().replace(/ |-/g, '') === 'BRANCHONE') {
                            console.log(index); -------------- 3                              
                        }
                    });
                }
            });

在这种情况下,rows.length = 2。 1的Console.log按预期输出0和1但是2和3的console.log输出为2,因为然后调用是异步的。因为异步调用并行运行,同时index的值更新为2(index ++)。

有关如何在异步调用中跟踪同步变量(索引)的任何想法吗?

1 个答案:

答案 0 :(得分:1)

我通常做的是将回调函数包装在另一个函数中以捕获新范围中的sync变量。为了说明,你现在拥有的是有效的:

var callback = function(text) {
  // use text and index...
};
async_call(...).then(callback);

问题当然是index变量(由回调函数捕获)在创建回调后发生变化。因为回调函数使用闭包来捕获对该值的引用,所以它最终会看到更改的值。

要在特定循环迭代期间捕获index的值,您可以使用不会更改的新变量创建新范围。基本上,您创建另一个函数并使用当前index调用它,函数的参数捕获该特定值。然后你可以让该函数返回另一个用作回调的函数。用于清除可怕描述的示例代码:

function createCallback(curIndex) {
  return function(text) {
    // use text and curIndex...
  };
}

//...

var callback = createCallback(index); // where index is the variable you are looping over
async_call(...).then(callback);

通过使createCallback成为匿名函数,可以更紧凑地编写:

var callback = (function(curIndex){
  return function(text) {
    // use text and curIndex...
  };
})(index);
async_call(...).then(callback);

有关JavaScript中的闭包和函数的详细信息,请参阅this comprehensive answer