在调用promise链之后调用Q promise函数

时间:2017-03-20 18:12:12

标签: javascript node.js promise q

我在使用Q promise库的Node.js应用程序中工作。我有两组promise链,一个用于控制流,一个用于调用服务方法,我从中检索数据,我的问题是,我需要将promise链的返回值传递给我的另一个promise链。

MyExample.js

bookService.getBookById(bookId)
  .then(bookDetals)
  .then(function(returnValue) { // <- (A)
    res.send(200, returnValue); // <- (C)
    return returnValue;
  }).catch(function(error) {
    logger.error('Error getting values');
    res.send(500, error);
  });


bookDetals = function(book) {
  myService.retrieveATypeData(book, bookId)
    .then(function(bookData) {
      myService.retrieveBTypeData(bookId)
        .then(function(bdata) {
          bookData[bTypeData] = bdata;
          myService.retrieveCTypeData(bookId)
            .then(function(cdata) {
              bookData[cTypeData] = cdata;
            }).done(function() {
              return bookData; // <- (B)
            })
        });
    });
};

在上面的代码中,我正在调用 bookService.getBookById(bookId)并获取该书。然后我调用bookDetals函数,这是一个承诺链。但我的问题是它在promise链接之前返回 returnValue 。如何获得promise链的返回值(在行(B)中)以返回到位(C)。目前它返回之前。所以到位C它说未定义。

2 个答案:

答案 0 :(得分:0)

由于您正在使用Node,我将转向ES6 Promises。如果您当前的版本尚不支持ES6 Promises,我建议您切换到为您填充的库(es6-promise)。使用ES6,您可以执行以下操作:

// mock async promise
const getThing = id => (
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        id
      });
    }, 250);
  })
);

// mock async promise
const getDetailsA = thing => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Object.assign({}, thing, {
        a: 'purple'
      }));
    }, 250);
  })
};

// mock async promise
const getDetailsB = thing => (
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Object.assign({}, thing, {
        b: 'monkey'
      }));
    }, 250);
  })
);

// mock async promise
const getDetailsC = thing => (
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Object.assign({}, thing, {
        c: 'dishwasher'
      }));
    }, 250);
  })
);

getThing('123')
  .then(getDetailsA)
  .then(getDetailsB)
  .then(getDetailsC)
  .then(console.log)
  .catch(console.error);

答案 1 :(得分:-1)

您需要返回promise

bookDetals = function(book) {
  return Q.Promise(function(resolve, reject, notify) {
    myService.retrieveATypeData(book, bookId)
        .then(function(bookData) {
          myService.retrieveBTypeData(bookId)
            .then(function(bdata) {
              bookData[bTypeData] = bdata;
              myService.retrieveCTypeData(bookId)
                .then(function(cdata) {
                  bookData[cTypeData] = cdata;
                }).done(function() {
                  resolve(bookData); // <- (B)
                })
            });
        });
  }  
}

<小时/> 的修改

deferred是一种反模式here。老实说,最好使用polyfill,因为Promise符合es6规范。