使用 .join() 在异步承诺中调用异步承诺
Calling async promises inside async promise using .join()
我正在使用 node/epxress、mysql 和 bluebird。
我目前正在客户端请求后执行异步数据库操作。在第一个数据库操作的回调中,我必须先执行一些计算,然后再执行两次数据库查询,以便为客户端提供正确的结果。
我的代码被分离到一个控制器 class 中,它处理 get/ post 请求。中间是一个用于业务逻辑的服务 class,它与数据库 class 对话,后者在数据库中进行查询。
我目前能够执行第一个和第二个数据库请求。
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;
但即使这样也无济于事。
Currently I just require Bluebird as Promise in my database class.
所以现在我的全部服务 class。
'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();
有人能给我一个正确的例子吗?
编辑:
这是我在我的数据库调用中使用的示例代码,return 数据库结果和承诺
return Promise.using(dbConnection.getConnection(), function (conn) {
return conn.queryAsync(sql, [departmentID])
.then(function (result) {
return result;
})
.catch(function (err) {
return err;
});
});
Promise.join
很好,但它可能不适合您的情况。 Promise.all
将像您那样将多个承诺组合成一个解决方案:
.then(result => Promise.all([result, departmentDatabase.countUser(departmentID), departmentDatabase.blockedDaysOfResponsible(departmentID)])]))
然后您可以将该结果(数组)传播到函数调用中:
.spread(function(a, b, c) {
console.log("Results", a, b, c);
});
Promise.all
接受一个 Promise 数组,等待它们全部解决(或拒绝),然后继续将有序数组中的结果放入后续 .then
(或其他 promise) ) 条款。
如果您正在寻找一个可以更轻松地使用 promises 控制流程的模块,那么您可能会喜欢 relign。 Promise.all
在这里可以解决问题,但如果您需要已解决的结果,那么 relign.parallel
或 relign.series
可能更适合您。
我正在使用 node/epxress、mysql 和 bluebird。
我目前正在客户端请求后执行异步数据库操作。在第一个数据库操作的回调中,我必须先执行一些计算,然后再执行两次数据库查询,以便为客户端提供正确的结果。
我的代码被分离到一个控制器 class 中,它处理 get/ post 请求。中间是一个用于业务逻辑的服务 class,它与数据库 class 对话,后者在数据库中进行查询。
我目前能够执行第一个和第二个数据库请求。
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;
但即使这样也无济于事。
Currently I just require Bluebird as Promise in my database class.
所以现在我的全部服务 class。
'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();
有人能给我一个正确的例子吗?
编辑:
这是我在我的数据库调用中使用的示例代码,return 数据库结果和承诺
return Promise.using(dbConnection.getConnection(), function (conn) {
return conn.queryAsync(sql, [departmentID])
.then(function (result) {
return result;
})
.catch(function (err) {
return err;
});
});
Promise.join
很好,但它可能不适合您的情况。 Promise.all
将像您那样将多个承诺组合成一个解决方案:
.then(result => Promise.all([result, departmentDatabase.countUser(departmentID), departmentDatabase.blockedDaysOfResponsible(departmentID)])]))
然后您可以将该结果(数组)传播到函数调用中:
.spread(function(a, b, c) {
console.log("Results", a, b, c);
});
Promise.all
接受一个 Promise 数组,等待它们全部解决(或拒绝),然后继续将有序数组中的结果放入后续 .then
(或其他 promise) ) 条款。
如果您正在寻找一个可以更轻松地使用 promises 控制流程的模块,那么您可能会喜欢 relign。 Promise.all
在这里可以解决问题,但如果您需要已解决的结果,那么 relign.parallel
或 relign.series
可能更适合您。