在调用 promise 链后调用 Q promise 函数
Call a Q promise function after promise chain invoked
我正在使用带有 Q promise 库的 Node.js 应用程序。我有两组承诺链,一组用于控制流程,一组用于调用我从中检索数据的服务方法,我的问题是,我需要将承诺链的 return 值获取到我的另一个承诺链.
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 函数,它是一个承诺链。但我的问题是 return 是 returnValue 在 promise 链结束之前。我怎样才能将 promise 链的 return 值(在 (B) 行)到 return 就位 (C)。当前它 return 之前。所以在 C 位置它说未定义。
你需要return一个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 is an anti-pattern discussed here. Honestly, it might be best to use a polyfill since Promise 在 es6 规范中。
既然你在使用 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);
我正在使用带有 Q promise 库的 Node.js 应用程序。我有两组承诺链,一组用于控制流程,一组用于调用我从中检索数据的服务方法,我的问题是,我需要将承诺链的 return 值获取到我的另一个承诺链.
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 函数,它是一个承诺链。但我的问题是 return 是 returnValue 在 promise 链结束之前。我怎样才能将 promise 链的 return 值(在 (B) 行)到 return 就位 (C)。当前它 return 之前。所以在 C 位置它说未定义。
你需要return一个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 is an anti-pattern discussed here. Honestly, it might be best to use a polyfill since Promise 在 es6 规范中。
既然你在使用 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);