2016-11-11 18 views
0

私はnode/epxress、mysql、およびbluebirdを使用しています。.within()を使用してasync promison内でasyncを呼び出すことを約束します。

私は現在、クライアントが要求した後に非同期データベース操作を行っています。最初のデータベース操作のコールバックの中で、最初にいくつかの計算を実行してから、クライアントに正しい結果を提供するために必要なさらに2つのデータベースクエリを実行しなければなりません。

マイコードは、get/postリクエストを処理するControllerクラスに分かれています。真ん中にはビジネスロジック用のサービスクラスがあり、データベース内でクエリを実行するデータベースクラスと通信します。

現在、第1および第2のデータベースリクエストを実行できます。

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; 
      }); 
    } 

しかし、3番目の実行しようとすると私はトラブルに走っています。 この問題の解決策として、私は.all()または(さらに良い).join()を指摘したBluebird Docsを読んだ。しかしどちらかを使ってみると私のために働いていませんでした。

私が.join()と試してみると、常にjoin is not a functionという結果になりますが、私は他のすべての機能を使用できるので混乱しています。私も要求しようとしました

var Promise = require("bluebird"); 
var join = Promise.join; 

しかし、これは助けられませんでした。

現在のところ、私のデータベースクラスでは、プロミスとしてブルーバードが必要です。

ここに私のサービスクラス全体があります。

'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(); 

誰かが私にそれを正しく行う方法の例を教えていただけますか?

EDIT:

ここ

デシベル結果と

return Promise.using(dbConnection.getConnection(), function (conn) { 
      return conn.queryAsync(sql, [departmentID]) 
       .then(function (result) { 
        return result; 
       }) 
       .catch(function (err) { 
        return err; 
       }); 
     }); 
+0

だから、 '。()を '参加するには、' getVacation'機能から出てくる 'Promise'を使用している - それが(それはブルーバードの約束だ確保)を返すかを確認することが有利かもしれません。第二に、[ドキュメント](http://bluebirdjs.com/docs/api/promise.join.html)>ので、多分あなたの行は '.then((結果)=を読んでください、約束はjoin''に​​渡されるように指定Promise.join(Promise.resolve(結果)、departmentDatabase.countUser(DepartmentIdの)、departmentDatabase.blockedDaysOfResponsible(DepartmentIdの)、(A、B、C)=>、B、C])) ' –

+0

いっそ、と'Promise.all':.then(result => Promise.all([result、departmentDatabase.countUser(departmentID)、departmentDatabase.blockedDaysOfResponsible(departmentID)]))))' –

+0

以下の構文で問題があります。あなたのPromise.allの例。あなたはこれを答えとして、最高のconsole.log(a);それは私を助けてくれるでしょう。 .join()の例では、まだああはそれを得た 'ないfunction'エラー – BayLife

答えて

0

Promise.joinがいいです約束を返すために、私がDatabaseCallの内側に使用したサンプルコード - 私が、それはあなたの状況のベストを合わせていない可能性があります。

.then(result => Promise.all([result, departmentDatabase.countUser(departmentID), departmentDatabase.blockedDaysOfResponsible(departmentID)])]‌​))

次にあなたが関数呼び出しにその結果(配列)を広げることもできます:Promise.allあなたは、単一の解像度にそこに持っているように、いくつかの約束は結合します

.spread(function(a, b, c) { 
    console.log("Results", a, b, c); 
}); 

Promise.allの配列を受け取りプロミスは、それらのすべてが解決(または拒否)するのを待ってから、次の.then(または他の約束)句に順序付けられた配列で結果を続行します。

0

制御フローを約束するモジュールを探していれば、relignが好きかもしれません。 Promise.allここでそのトリックを行うかもしれませんが、解決された結果が必要な場合はrelign.parallelまたはrelign.seriesが良いでしょう。

関連する問題