Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise inside promise

I am trying to write this code with Promise. but I don't know how to write promise inside Promise and loop. I tried to think like this but insertBook function become asynchronously. How can I get bookId synchronously?

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");
  });
}
like image 873
通りすがりのおっさん Avatar asked May 31 '16 22:05

通りすがりのおっさん


People also ask

Can I use promise Inside promise?

Here we need to first declare a Promise by using the Promise syntax, and we will be using the then() method for its execution and then inside that then() method we will create another promise by using the same Promise syntax as illustrated above, and then we will call our result of first inside that new Promise.

Can promises be nested?

Nested Promise:These nested promises will have access to variables from their outer scope and are otherwise called “promise-pyramids”, which will grow to the right. If not done correctly, this promise pyramid can eventually lead to something called as Promise-Callback Hell .

How do you call multiple promises?

In this approach, we will use Promise. all() method which takes all promises in a single array as its input. As a result, this method executes all the promises in itself and returns a new single promise in which the values of all the other promises are combined together.

Does promise then return a promise?

Promise.prototype.then() The then() method returns a Promise . It takes up to two arguments: callback functions for the success and failure cases of the Promise .


1 Answers

You dont need to get bookid synchronously, you can handle it asynchronously correctly. Also, it is possible you want all book insertions happen sequentially, so I refactored the Promise.all part. (done that just to give you an idea. Promise.all should work fine if insertions in parallel are allowed). Furthermore, I think you shouldn't use Promise.bind. To be honest I dont even know what it does, one thing for sure: it doesn't work with standard promises. So here is an example how I think it should work:

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");
  });
}
like image 65
Tamas Hegedus Avatar answered Oct 21 '22 15:10

Tamas Hegedus