2016-05-31 24 views
7

Sto provando a scrivere questo codice con Promise. ma non so come scrivere promesse all'interno di Promise e loop. Ho provato a pensare in questo modo, ma la funzione di inserimento del libro diventa in modo asincrono. Come posso ottenere bookId in modo sincrono?Promessa promessa interna

update: function(items, quotationId) { 
    return new Promise(function(resolve, reject) { 
    knex.transaction(function (t) { 
     Promise.bind(result).then(function() { 
     return process1 
     }).then(function() { 
     return process2 
     }).then(function() { 
     var promises = items.map(function (item) { 
      var people = _.pick(item, 'familyName', 'firstNumber', 'tel'); 
      if (item.type === 'book') { 
      var book = _.pick(item, 'name', 'bookNumber', 'author'); 
      var bookId = insertBook(t, book); 
      var values = _.merge({}, people, {quotation: quotationId}, {book: bookId}); 
      } else { 
      var values = _.merge({}, people, {quotation: quotationId}); 
      } 
      return AModel.validateFor(values); 
     }); 
     return Promise.all(promises); 
     }).then(function(items) { 
     var insertValues = items.map(function (item) { 
      return People.columnize(item); 
     }); 
     return knex('people').transacting(t).insert(insertValues); 
     }).then(function() { 
     return process5 
     }).then(function() { 
     ........... 

     }).then(function() { 
     t.commit(this); 
     }).catch(t.rollback); 
    }).then(function (res) { 
     resolve(res); 
    }).catch(function(err) { 
     reject(err); 
    }); 
    }); 
} 

function insertBook(t, book){ 
    return Promise.bind(this).then(function() { 
    return Book.columnizeFor(book); 
    }).then(function (value) { 
    return knex('book').transacting(t).insert(value, "id"); 
    }); 
} 
+0

evitare il [ 'Promise' costruttore antipattern] (https://stackoverflow.com/q/23803743/1048572?What-is-the-promise- costruzione-antipattern-and-how-to-evitare-it)! – Bergi

risposta

0

Supponendo che insertBook restituisce una promessa che si possa fare

var people = _.pick(item, 'familyName', 'firstNumber', 'tel'); 
if (item.type === 'book') { 
    var book = _.pick(item, 'name', 'bookNumber', 'author'); 
    return insertBook(t, book) 
    .then(bookId => _.merge({}, people, {quotation: quotationId}, {book: bookId})) 
    .then(AModel.validateFor) 
} else { 
    return Promise.resolve(_.merge({}, people, {quotation: quotationId})) 
    .then(AModel.validateFor) 
} 
+0

Grazie per il vostro aiuto. Ce l'ho fatta!. ma ho ancora una domanda. questa tabella 'PEOPLE' ha la colonna 'book_id' che consente NULL. e la tabella 'Libro' ha colonna 'people_id' che non consente NULL. quindi ho pensato che dopo aver inserito People dovessi inserire i dati del libro. –

+0

Ho inserito i dati People in una volta. ma dovrei inserire quei dati People ogni volta per usare book_id che è stato inserito nella tabella del libro? –

+0

@ 通 り す が り の お っ さ ん si potrebbe fare che nel metodo 'insertBook', quello che vorrei fare è controllare se una persona con un id' people_id' esiste, se non allora crearlo prima e poi fare l'operazione per inserire il libro –

1

Non avete bisogno di ottenere BookID sincrono, si può gestire in modo asincrono in modo corretto. Inoltre, è possibile che tutti gli inserimenti di libri avvengano in modo sequenziale, quindi ho refactorato la parte Promise.all. (fatto questo solo per darti un'idea. Promise.all dovrebbe funzionare bene se sono consentiti inserimenti in parallelo). Inoltre, penso che non dovresti usare Promise.bind. Ad essere onesti, non so nemmeno cosa faccia, una cosa è certa: non funziona con le promesse standard. Quindi, ecco un esempio di come penso che dovrebbe funzionare:

update: function(items) { 
    return new Promise(function(resolve) { 
    knex.transaction(function (t) { 
     resolve(Promise.resolve().then(function() { 
     return process1; 
     }).then(function() { 
     return process2; 
     }).then(function() { 
     var q = Promise.resolve(), results = []; 
     items.forEach(function (item) { 
      q = q.then(function() { 
      var book = _.pick(item, 'name', 'bookNumber', 'author'); 
      return insertBook(t, book); 
      }).then(function(bookId) { 
      var people = _.pick(item, 'familyName', 'firstNumber', 'tel'); 
      var values = _.merge({}, people, {book: bookId}); 
      return AModel.validateFor(values); 
      }).then(function(item) { 
      results.push(item); 
      }); 
     }); 
     return q.then(function() { 
      return results; 
     }); 
     }).then(function(items) { 
     return process4 
     }).then(function() { 
     t.commit(result); 
     }).catch(function(e) { 
     t.rollback(e); 
     throw e; 
     })); 
    }); 
    }); 
} 

function insertBook(t, book){ 
    return Promise.resolve().then(function() { 
    return Book.columnizeFor(book); 
    }).then(function (value) { 
    return knex('book').transacting(t).insert(value, "id"); 
    }); 
}