2015-08-18 5 views
0

Следующий код на самом деле не делает то, что я хочу.Ждите обещаний из цикла for

function doIt() { 
    return new Promise (function (resolve, reject) { 
    var promises = []; 
    db.transaction(function(tx1){ 
     tx1.executeSql(function(tx2, rs) { 
     for (var i = i; i < N; i++) { 
      promises.push(db.transaction(function(tx3){ 
      ... 
      })); 
     } 
     }); 
    }); 
    Promise.all(promises).then(resolve); 
    }); 
} 

Сейчас он не работает, потому что Promise.all() запускается на выполнение, прежде чем все обещания в массиве, по крайней мере, я думаю, что это правильно.

Есть ли элегантный способ гарантировать, что все эти обещания закончены, прежде чем они закончится?

+1

'перед всеми обещаниями в массиве. нет. вызов 'push' и вызов' all' являются последовательными, поскольку они работают в одной и той же функции. мне кажется, что это должно сработать. – njzk2

+0

db.transaction не является последовательным. Я сделал оповещения после цикла и после завершения транзакций, и предупреждение после того, как цикл появился первым. – Odin

+0

, и этого не должно быть, иначе не было бы смысла использовать обещание. Но это не проблема, так как вы держите ссылку на обещание. Запишите размер массива, прежде чем называть 'Promise.all', я уверен, что все обещания есть. – njzk2

ответ

0

Вы можете просто двигаться, где Promise.all() расположен так, что он сразу же после цикла for закончил заполнение массива:

function doIt() { 
    return new Promise (function (resolve, reject) { 
    var promises = []; 
    db.transaction(function(tx1){ 
     tx1.executeSql(function(tx2, rs) { 
     for (var i = i; i < N; i++) { 
      promises.push(db.transaction(function(tx3){ 
      ... 
      })); 
     } 
     Promise.all(promises).then(resolve); 
     }); 
    }); 

    }); 
} 

FYI, смешивая обещания и обратные вызовы могут быть запутанным и делает последовательную обработку особенно трудной ошибки , tx1.executeSql() уже вернули обещание? Если да, то вы можете сделать что-то чисты, используя только обещание, которые уже созданы вашими функции базы данных, как это:

function doIt() { 
    return db.transaction.then(function(tx1) { 
     return tx1.executeSql().then(function(tx2, rs) { 
      var promises = []; 
      for (var i = i; i < N; i++) { 
       promises.push(db.transaction().then(function(tx3) { 
        ... 
       })); 
      } 
      return Promise.all(promises).then(resolve); 
     }); 
    }); 
} 

Это возвращает обещания из .then() обработчиков для автоматической цепи обещаний вместе.

+0

Кажется, что это идет в правильном направлении, но db.transaction.then (f) не будет выполнять f вообще, так как f не может прийти после транзакции, потому что это часть транзакции. – Odin

+0

@Odin - в какой библиотеке базы данных вы используете? – jfriend00

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