Ich verwende node/epxress, mysql und bluebird.Async-Versprechen innerhalb async Versprechen mit .join()
Ich mache derzeit eine asynchrone Datenbankoperation, nachdem der Client es angefordert hat. Innerhalb des Callbacks der ersten Datenbankoperation muss ich zuerst einige Berechnungen durchführen und danach zwei weitere Datenbankabfragen durchführen, die benötigt werden, um dem Client das korrekte Ergebnis zu liefern.
Mein Code ist in eine Controller-Klasse unterteilt, die die Get/Post-Anfrage behandelt. In der Mitte eine Serviceklasse für Geschäftslogik, die mit einer Datenbankklasse kommuniziert, die in der Datenbank abfragt.
Ich bin derzeit in der Lage, die erste und zweite Datenbankanforderung durchzuführen.
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;
});
}
Aber wenn ich versuche, die dritte durchzuführen, stoße ich in Schwierigkeiten. Für eine Lösung dieses Problems lese ich die Bluebird Doc's, die mich auf .all()
oder (noch besser) .join()
wies. Aber zu versuchen, beide zu benutzen, hat nicht für mich funktioniert.
Wenn ich es mit .join()
versuche ist immer Ergebnisse in join is not a function
, die ich verwirrend finde, weil ich alle anderen Funktionen verwenden kann. Ich habe auch versucht,
var Promise = require("bluebird");
var join = Promise.join;
zu verlangen, aber nicht einmal das half.
Derzeit benötige ich nur Bluebird als Promise in meiner Datenbankklasse.
Also hier jetzt meine gesamte Serviceklasse.
'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();
Kann jemand mir ein Beispiel geben, wie man es richtig macht?
EDIT:
Hier ist ein Beispiel-Code Ich bin in meinem databaseCall verwenden, das DB Ergebnis und das Versprechen zurückzukehren
return Promise.using(dbConnection.getConnection(), function (conn) {
return conn.queryAsync(sql, [departmentID])
.then(function (result) {
return result;
})
.catch(function (err) {
return err;
});
});
Also, weil Sie verwenden '.join() ', verwenden Sie die' Promise', die aus der 'getVacation'-Funktion kommt - so könnte es vorteilhaft sein zu sehen, was es zurückgibt (es ist ein Bluebird-Versprechen). Zweitens geben die [docs] (http://bluebirdjs.com/docs/api/promise.join.html) an, dass Promises an 'join' übergeben werden sollten, also sollte Ihre Zeile vielleicht' .then ((result) => Promise.join (Promise.resolve (Ergebnis), departmentDatabase.countUser (departmentID), departmentDatabase.blockedDaysOfResponsible (departmentID), (a, b, c) => [a, b, c])) ' –
Oder noch besser, mit 'Promise.all':' .then (Ergebnis => Promise.all ([result, departmentDatabase.countUser (departmentID), departmentDatabase.blockedDaysOfResponsible (departmentID)]])) ' –
Ich habe Probleme mit der Syntax in Ihr Promise.all-Beispiel. Könnten Sie das bitte als Antwort formulieren, am besten mit einem Beispiel console.log (a) ;? das würde mir sehr helfen. Das .join() Beispiel läuft immer noch in den 'no a function' Fehler – BayLife