2016-01-15 1 views
3

Немного новичок в javascript, но из того, что я прочитал, все ценности в рамках обещания в основном используются только в рамках этого обещания?Как выйти из цикла из возвращаемого значения обещания?

В принципе getSomething() возвращает 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() 
     } 
    }); 
} 

Причиной, побуждающей я использую для цикла, потому что мне нужно найти текст, соответствующий в сильной , затем нажмите кнопку в теге td ниже.

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

Вы не можете использовать обещание с циклом. Обещания являются асинхронными, то есть они будут запускаться только после запуска всего вашего другого синхронного кода. –

+0

@MikeC почему после? Они будут работать в одно и то же время. – Calin

+0

@Calin Я имею в виду, что функция '.then' не будет выполняться до тех пор, пока не завершится весь синхронный код. Такая же идея, как использование 'setTimeout' или' setInterval'. –

ответ

6

Есть обещания, связанные, которые транспортир добавляет к Control Flow queue, вы не можете читать и обрабатывать цикл for + break, как обычно делаете в синхронном коде «сверху вниз».

Общее решение этой проблемы заключается в использовании рекурсии + замыкания, см примеры решения здесь:


причина, почему я с помощью цикл for - это потому, что мне нужно найти соответствующий текст в сильном теге, затем нажмите кнопку в 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(); 
+0

Можете ли вы взглянуть на мое обновление? Я просмотрел ваш ответ http://stackoverflow.com/a/31208548/4188135 и другие, но они, похоже, применяются к экземплярам, ​​где действие click() выполняется в строке/теге, которая соответствует. Но мне нужно как-то сделать действие во второй строке, возвращенной репитером. Надеюсь, что имеет смысл –

+0

@ yob-v-u уверен, спасибо за то, что проблема стала более конкретной. Обновленный ответ, надеюсь, что это поможет. – alecxe

1

Если вы действительно хотите сделать что-то вроде этого вам придется использовать when, он возвращает новое обещание.

when(promise1, promise2, promise3).done(function (promise1, promise2, promise3) { 
} 
  • Когда все данные promisses будут решены, новое обещание решить
  • Когда один обещание не удается, новое обещание не удается
+0

спасибо, не могли бы вы поделиться больше примеров использования 'when'? возможно, ссылка – eLRuLL

Смежные вопросы