如何在for循环中处理量angular器promise?

我正在尝试做一些量angular器testing,并没有在for循环中解决承诺。

在我的testing案例中,我想在ng-repeat元素中find一个特定的节点。

这里是find这样一个节点的代码:

var firstProfileNode = function(nodename, profile){ element.all(by.repeater('node in tree_nodes')).then(function(treeNodes){ for(var i=0; i<treeNodes.length; i++){ var node = treeNodes[i].element(by.css('.tree-dnd-handle')); node.getText().then(function(text){ console.log(i+" : "+text); if (profile){ var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; var regx = new RegExp(pattern); if(regx.test(text)){ console.log('found') return node; } }else{ if(text === nodename){ return node; } } }); } }); }; var test = firstProfileNode('ISR', true); 

这里是控制台输出:

 23 : edison (4 devices) 23 : ed21-mbr2 23 : ed22-mbr1 23 : ed22-mbr2 23 : ed21-mbr1 23 : c2800-12 23 : L1 (4 devices) 23 : c887VAM-1 23 : c891-1 23 : c887-1 23 : c3850-1 23 : ISR (3 devices) found 23 : 3700 (2 devices) 23 : c3745-2 23 : c3745-1 23 : c2921-1 23 : c2800-11 23 : N7K (3 devices) 23 : n7k-2 23 : n7k-1 23 : n7k-3 23 : c2800-13 23 : c2800-14 

问题是在for循环完成后,getText()允许parsing。 这个证据是由logging的“我”值23,最后一个计数。 我正在寻找一种方法来让for循环等待承诺或另一种方式来完全find节点。

您期待的代码是从上到下同步执行的,但它实际上是asynchronous的 – 循环将在第一个getText()被parsing的时刻结束。

我认为你需要的是一个filter()

 var firstProfileNode = function(nodename, profile) { return element.all(by.repeater('node in tree_nodes')).filter(function(treeNode) { return treeNode.element(by.css('.tree-dnd-handle')).getText().then(function(text) { if (profile) { var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; var regx = new RegExp(pattern); return regx.test(text); } else { return text === nodename; } }); }).first(); }; 

firstProfileNode()函数将返回对应于所需过滤node元素的ElementFinder实例。

这是一个相当普遍的现象。

承诺解决asynchronous之后整个循环已经运行,因此只有最后一个节点被返回( i总是23)

通常的做法是把callback(即)

 function fooBar(node, i) { node.getText().then(function(text){ console.log(i+" : "+text); if (profile){ var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; var regx = new RegExp(pattern); if(regx.test(text)){ console.log('found') return node; } }else{ if(text === nodename){ return node; } } }); } 

在一个单独的方法中,以便每个nodeivariables在该方法的closed in scope并且不会更改。 然后简单地调用该方法。

你可以尝试这样的事情:

 var firstProfileNode = function(nodename, profile){ element.all(by.repeater('node in tree_nodes')).then(function(treeNodes){ for(var i=0; i<treeNodes.length; i++){ var node = treeNodes[i].element(by.css('.tree-dnd-handle')); getNodeText(i, node); } }); }; var getNodeText = function(i, node) { node.getText().then(function(text){ console.log(i+" : "+text); if (profile){ var pattern = '^' +nodename+' \\(\\d+ devices\\)$'; var regx = new RegExp(pattern); if(regx.test(text)){ console.log('found') return node; } }else{ if(text === nodename){ return node; } } });} var test = firstProfileNode('ISR', true);