如何在for循环中处理量角器承诺?

时间:2017-04-04 02:03:03

标签: javascript angularjs node.js protractor

我试图做一些量角器测试,并且在for循环中没有解决承诺。

在我的测试用例中,我想在ng-repeat元素中找到一个特定的节点。

以下是查找此类节点的代码:

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

问题是getText()promise在for循环完成后解析。记录的&#39; i&#39;值为23,即最终计数。我正在寻找一种方法让for循环等待承诺或其他方式完全找到节点。

3 个答案:

答案 0 :(得分:2)

您希望代码可以从上到下同步执行,但它实际上是异步的 - 在首先解析getText()时,循环将结束。

我认为您需要的是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实例。

答案 1 :(得分:0)

这种情况很常见。

Promise解析asynch整个for循环运行后因此只返回最后一个节点(i总是23)

一种常见的方法是附上回调(即)

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;
                }
            }
        });    
}

在另一种方法中,每个nodei变量在该方法中都是closed in scope且不会发生变化。然后简单地调用方法。

答案 2 :(得分:0)

您可以尝试这样的事情:

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);