2016-05-31 118 views
7

我正在尝试用Promise编写此代码。但我不知道如何在诺言和循环中写诺言。 我试图这样想,但insertBook函数变得异步。 如何同步获取bookId?承诺内承诺

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

避免['Promise'构造反模式](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-建筑反模式和如何对避免-吧)! – Bergi

回答

0

假设insertBook返回一个承诺,你可以做

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

谢谢你的帮助。我做到了!。但我还有一个问题。这个'PEOPLE'表具有允许NULL的列'book_id'。和'书'表有colum'people_id',它不允许NULL。所以我想在插入People之后,我必须插入Book数据。 –

+0

我一次插入了人员数据。但是我应该每次插入这些人员数据以便使用插入到Book表中的book_id? –

+0

@你可以在方法'insertBook'中做到这一点,我要做的就是检查一个id为people_id的人是否存在,如果不存在,那么先创建它,然后执行事务插入书 –

1

你不需要得到BOOKID同步,你可以异步正确处理它。此外,您可能希望所有书籍插入顺序发生,因此我重构了Promise.all部分。 (这样做只是为了给你一个想法,如果允许并行插入,Promise.all应该可以正常工作)。此外,我认为你不应该使用Promise.bind。说实话,我甚至不知道它做了什么,肯定的一件事:它不符合标准的承诺。因此,这里是一个例子,我怎么想它应该工作:

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