最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - How to break out of a loop from a returned promise value? - Stack Overflow

matteradmin5PV0评论

A bit new to javascript, but from what I've read, all values within a promise are basically only usable within that promise right?

Basically getSomething() returns true/false from another promise. And I was to break out of the for loop if true. I tried something like this, but I'm sure it's not right as it's not printing out "breaking"

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

The reason I'm using the for loop is because I need to find a matching text in the strong tag, then click on the button in the td tag below it.

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

A bit new to javascript, but from what I've read, all values within a promise are basically only usable within that promise right?

Basically getSomething() returns true/false from another promise. And I was to break out of the for loop if true. I tried something like this, but I'm sure it's not right as it's not printing out "breaking"

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

The reason I'm using the for loop is because I need to find a matching text in the strong tag, then click on the button in the td tag below it.

<tbody>
    <tr ng-repeat="something">
        <td>
            <strong>{{x.name}}</strong>
        </td>
        <td>
            <button>{{x.button}}</button>
        </td>
    </tr>
</tbody>
Share Improve this question edited Jan 15, 2016 at 21:53 yob-v-u asked Jan 15, 2016 at 20:58 yob-v-uyob-v-u 1194 silver badges15 bronze badges 5
  • You can't use promises with a for loop. Promises are asynchronous, meaning they'll run only after all of your other synchronous code runs. – Mike Cluck Commented Jan 15, 2016 at 20:59
  • @MikeC why after? They will run in the same time. – Calin Commented Jan 15, 2016 at 21:01
  • @Calin What I mean is that the .then function won't execute until after all synchronous code has plete. Same idea as using setTimeout or setInterval. – Mike Cluck Commented Jan 15, 2016 at 21:02
  • @MikeC then will return a new promise, the callback function (it has a syntax error) in then will get executed once somebody calls resolve on this promise, nobody does that in this code. I think the poster needs to do some more readup on promises. – Calin Commented Jan 15, 2016 at 21:13
  • 1 @Calin The then callback is fine. It's an arrow function. Yes, it would return a promise which explicitly means the value won't be accessible in time to break out of the loop. See alecxe's answer. – Mike Cluck Commented Jan 15, 2016 at 21:16
Add a ment  | 

2 Answers 2

Reset to default 6

There are promises involved, which Protractor adds to the Control Flow queue, you cannot read and handle the for loop + break as you would usually do in a synchronous "top to bottom" code.

The mon solution to this problem is to use recursion+closures, see sample solutions here:

  • Asynchronous for cycle in JavaScript
  • AngularJS & Protractor - Perform .click() while an element .isDisplayed()

The reason I'm using the for loop is because I need to find a matching text in the strong tag, then click on the button in the td tag below it.

One option would be to use the by.xpath() locator:

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

where label is the strong value you are looking for.

Or, a more protractor-specific approach would be to use 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();

If you really want to do something like this you will have to use when, it will return a new promise.

when(promise1, promise2, promise3).done( function (promise1, promise2, promise3) {
}
  • When all the given promisses are resolved, the new promise is resolved
  • When one promise fails, the new promise fails
Post a comment

comment list (0)

  1. No comments so far