如何从返回的promise值中跳出循环?

时间:2016-01-15 20:58:44

标签: javascript angularjs protractor

javascript有点新鲜,但从我所读过的内容来看,承诺中的所有值基本上只能在该承诺中使用吗?

基本上,getSomething()从另一个promise返回true / false。如果是真的,我就要打破for循环。我试过这样的事情,但我确定它不对,因为它没有打印出来"打破"

for(...) {
    var bool = this.getSomething(a,b,c).then((flag) => {
        if (flag == true) {
            console.log('returning true');
            return true; // can't use break so have to set boolean - eslint gives me unsyntactical break
        }
    });

    if (bool == true) {
        console.log('breaking');
        break;
    }
}

getSomething(a,b,c) {
    const n = b[a].element(by.binding('something'));
    return n.getText().then((text) => {
        if (text === c) {
        return clickSomething();        // returns true after click()
        }
    });
}

我使用for循环的原因是因为我需要在强标记中找到匹配的文本,然后点击它下面的td标记中的按钮。

<tbody>
    <tr ng-repeat="something">
        <td>
            <strong>{{x.name}}</strong>
        </td>
        <td>
            <button>{{x.button}}</button>
        </td>
    </tr>
</tbody>

2 个答案:

答案 0 :(得分:6)

所涉及的承诺,Protractor添加到Control Flow queue,您无法读取和处理for循环+中断,就像通常在同步“从上到下”代码中所做的那样。

此问题的常见解决方案是使用递归+闭包,请参阅此处的示例解决方案:

  

我使用for循环的原因是因为我需要在strong标签中找到匹配的文本,然后点击它下面的td标签中的按钮。

一种选择是使用by.xpath() locator

element(by.xpath("//td[strong = '" + label + "']/following-sibling::td/button")).click();

其中label是您要查找的strong值。

或者,更具有量角器的方法是使用filter()

var rows = element.all(by.repeater("something"));

var filteredRow = rows.filter(function (row) {
    return row.element(by.binding("x.name")).getText().then(function (name) {
        return name === label; 
    });
}).first();

filteredRow.element(by.binding("x.button")).click();

答案 1 :(得分:1)

如果你真的想做这样的事情你将不得不使用when,它将返回一个新的承诺。

when(promise1, promise2, promise3).done( function (promise1, promise2, promise3) {
}
  • 当所有给定的承诺得到解决后,新的承诺得到解决
  • 当一个承诺失败时,新承诺失败