我正在使用node/epxress,mysql和bluebird。使用.join在異步承諾中調用異步承諾
我現在正在做一個異步數據庫操作後,客戶端請求它。在第一個數據庫操作的回調中,我必須首先執行一些計算,然後再執行兩個數據庫查詢,這些查詢是爲客戶端提供正確結果所必需的。
我的代碼被分成一個Controller類,它處理get/post請求。在中間是業務邏輯的服務類,它與在數據庫中查詢的數據庫類進行對話。
我目前能夠執行第一個和第二個數據庫請求。
getVacation(departmentID) {
return departmentDatabase.getVacation(departmentID)
.then(result => [ result, result.map(entry => this.getDateRange(new Date(entry.dateFrom), new Date(entry.dateTo))) ])
.spread(function(result, dateRange){
var mergedDateRange = [].concat.apply([], dateRange);
var counts = {};
mergedDateRange.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
return [{"vacationRequest": result, "dateRange": dateRange, "countedDateRange": counts}];
})
.then(result => [result, departmentDatabase.countUser(departmentID)])
.spread(function (result, userOfDepartmentCount){
console.log(userOfDepartmentCount);
console.log(result);
//console.log(blocked);
return departmentID; //return just for not running into timeout
})
.catch(err => {
// ...do something with it...
// If you want to propagate it:
return Promise.reject(err);
// Or you can do:
// throw err;
});
}
但是,當試圖執行第三次我遇到麻煩。 對於這個問題的解決方案,我閱讀了Bluebird Docs,它指向我.all()
或(更好).join()
。但試圖使用他們中的任何一個都沒有爲我工作。
如果我嘗試.join()
總是導致join is not a function
,這讓我感到困惑,因爲我可以使用所有其他功能。我也試過要求
var Promise = require("bluebird");
var join = Promise.join;
但是這甚至都沒有幫助。
目前我只需要Bluebird作爲我的數據庫類中的Promise。
所以這裏現在我的整個服務類。
'use strict';
var departmentDatabase = require('../database/department');
var moment = require('moment');
class DepartmentService {
constructor() {
}
getVacation(departmentID) {
return departmentDatabase.getVacation(departmentID)
.then(result => [ result, result.map(entry => this.getDateRange(new Date(entry.dateFrom), new Date(entry.dateTo))) ])
.spread(function(result, dateRange){
var mergedDateRange = [].concat.apply([], dateRange);
var counts = {};
mergedDateRange.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
return [{"vacationRequest": result, "dateRange": dateRange, "countedDateRange": counts}];
})
//THIS DOES NOT WORK
.join(result => [result, departmentDatabase.countUser(departmentID), departmentDatabase.blockedDaysOfResponsible(departmentID)])
.spread(function (result, userOfDepartmentCount, blocked){
console.log(userOfDepartmentCount);
console.log(result);
console.log(blocked);
return departmentID;
})
.catch(err => {
// ...do something with it...
// If you want to propagate it:
return Promise.reject(err);
// Or you can do:
// throw err;
});
}
getDateRange(startDate, stopDate) {
var dateArray = [];
var currentDate = moment(startDate);
while (currentDate <= stopDate) {
dateArray.push(moment(currentDate).format('YYYY-MM-DD'))
currentDate = moment(currentDate).add(1, 'days');
}
return dateArray;
}
}
module.exports = new DepartmentService();
是否有人能夠給我一個例子如何做到這一點的權利?
編輯:
這裏用我的databaseCall內,返回DB結果和承諾
return Promise.using(dbConnection.getConnection(), function (conn) {
return conn.queryAsync(sql, [departmentID])
.then(function (result) {
return result;
})
.catch(function (err) {
return err;
});
});
所以,因爲你使用'。join()',你使用'getVacation'函數出來的'Promise' - 所以看看它返回的是什麼(確保它是一個Bluebird Promise)可能是有利的。其次,[docs](http://bluebirdjs.com/docs/api/promise.join.html)指定Promises應該傳遞給'join',所以也許你的行應該讀取'.then((result)=> Promise.join(Promise.resolve(result),departmentDatabase.countUser(departmentID),departmentDatabase.blockedDaysOfResponsible(departmentID),(a,b,c)=> [a,b,c]))' –
或者更好, 'Promise.all':'.then(result => Promise.all([result,departmentDatabase.countUser(departmentID),departmentDatabase.blockedDaysOfResponsible(departmentID)])]))' –
我有一些麻煩的語法你的Promise.all例子。您能否將此作爲答案來制定,最好以console.log(a)爲例;?這會幫助我很多。 .join()示例仍然會出現在「不是函數」錯誤中 – BayLife