简体   繁体   English

调用Promise链后调用Q Promise函数

[英]Call a Q promise function after promise chain invoked

I am working in a Node.js app with Q promise library. 我正在使用带有Q Promise库的Node.js应用程序。 I have two set of promise chains and one is for controlling the flow and one for calling service methods where I retrieve data from, My question is, I need to get the return value of the promise chain to my other promise chain. 我有两组承诺链,一组用于控制流程,另一组用于调用从中检索数据的服务方法。我的问题是,我需要将承诺链的返回值传递给我的其他承诺链。

MyExample.js 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)
            })
        });
    });
};

In the above code, I am calling bookService.getBookById(bookId) and getting the book. 在上面的代码中,我正在调用bookService.getBookById(bookId)并获取书。 Then I am calling bookDetals function which is a promise chain. 然后我调用bookProtals函数,这是一个承诺链。 But my problem is it returns the returnValue before the promise chains over. 但是我的问题是,在诺言链结束之前,它会返回returnValue How can I get the return value of promise chain (in line (B)) to return in place (C). 我如何获得承诺链的返回值(在行(B)中)以返回到位(C)。 Currently it return before. 目前它返回之前。 so in place C it says undefined. 因此,在C语言中,它表示未定义。

Since you are using Node, I would move towards ES6 Promises. 由于您正在使用Node,因此我将转向ES6 Promises。 If your current version does not yet support ES6 Promises, I would recommend you switch over to a library ( es6-promise ) that polyfills it for you. 如果您当前的版本尚不支持ES6 Promises,建议您切换到为您多填充的库( es6-promise )。 With ES6, you could do something like this: 使用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);

You need to return a 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)
                })
            });
        });
  }  
}


edit : 编辑

deferred is an anti-pattern discussed here . deferred此处讨论的反模式。 Honestly, it might be best to use a polyfill since Promise is in the es6 spec. 老实说,它可能是最好使用填充工具 ,因为承诺是在ES6规范。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM