【发布时间】:2016-11-11 08:58:35
【问题描述】:
我正在使用 node/epxress、mysql 和 bluebird。
我目前正在客户端请求后执行异步数据库操作。在第一个数据库操作的回调中,我必须先执行一些计算,然后再执行两个数据库查询,这些查询是为客户端提供正确结果所必需的。
我的代码被分成一个控制器类,它处理 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 Doc´s,它指向我 .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 中使用的示例代码,用于返回数据库结果和承诺
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- 因此查看它返回的内容可能是有利的(确保它是蓝鸟承诺)。其次,docs 指定应将 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() 示例仍然遇到
not a function错误 -
啊,明白了。你想为此创建一个答案,否则我会的。
.then(result => Promise.all([result, departmentDatabase.countUser(departmentID), departmentDatabase.blockedDaysOfResponsible(departmentID)])).spread(function(a, b, c){ console.log(a); console.log(b); console.log(c); return 1; })
标签: javascript node.js express asynchronous bluebird