2017-04-12 15 views
1

私はかなり新しい約束事で、私は物事を扱っていると思っていましたが、はっきりと私はしません。promise chain breaks with .all()

次のコードは、X個のテーブル名(getTableName())を取得し、getData()に渡して各テーブルをループしてデータを取得するためのコードです。次にPromise.all()を呼び出してそれらを解決し、チェーン内の次のリンク(createFile())にデータを渡そうとしますが、Promise.all()はcreateFile()に移動した後に解決します。

これは私を噛んで戻ってくる「反パターン」の例ですか?もしそうなら、誰かが私がやるべきことを達成できるようにどのように再構成すべきかを提案することができますか?

ありがとうございます!

exports.getRawDataForExport = function(data) { 
    return new Promise(function(resolve, reject) { 

    var getTableName = function() { 
     return knex('monitored_parameter') 
     .where('device_id', data.device_id) 
     .whereIn('internal_name', data.param) 
     .select() 
     .then(function(rows) { 
      if(rows) { 
      var runningResult = {}; 
      for(var i = 0; i < rows.length; i++) { 
       var tbl = {"table" : 'monitored_parameter_data_' + rows[i].id, "param" : rows[i].display_name}; 
       runningResult.table = []; 
       runningResult.table.push(tbl); 
      } 

      return runningResult; 

      } else { 
      // if no MP row(s) found we cannot proceed 
      throw new Error("No history found for that parameter."); 
      } 
     }); 
    } 

    var getData = function(runningResult) { 
     var promises = []; 

     if(data.date_start && data.date_end) { 
     // grab within range 

     for(var i = 0; i < runningResult.table.length; i++) { 
      promises.push(
      knexHistory(runningResult.table[i].table) 
       .select('created', 'data_value as value', 'unit') 
       .whereBetween('created', [data.date_start, data.date_end]) 
      ); 
     } 

     // *** the chain moves on to createFile() before this data is passed along 
     Promise.all(promises).then(function(data) { 
      console.dir('inside promises.all'); 
      console.dir(data); 
      runningResult.data = data; 
      return runningResult; 
     }); 

     } else { 
     // grab all 
     for(var i = 0; i < runningResult.table.length; i++) { 
      promises.push(
      knexHistory(runningResult.table[i].table) 
       .select('created', 'data_value as value', 'unit') 
      ); 
     } 

     // *** the chain moves on to createFile() before this data is passed along 
     Promise.all(promises).then(function(data) { 
      console.dir('inside promises.all'); 
      console.dir(data); 
      runningResult.data = data; 
      return runningResult; 
     }); 
     } 
    } 

    var createFile = function(runningResult) { 

     var files = [], 
      zipFileName = filePathExport + 'Data_Export.zip'; 

     for(var i = 0; i < runningResult.table.length; i++) { 
     var fields = ['created', 'value', 'unit'], 
      csvFileName = runningResult.param + '_export.csv', 
      csvFilePath = filePathExport + runningResult.param + '_export.csv'; 

     var csv = json2csv({data : runningResult.data[i], fields : fields, doubleQuotes : ''}); 

     fs.writeFileSync(csvFilePath, csv); 

     files.push(csvFilePath); 
     } 

     var zip = new admzip(); 

     for(var j = 0; j < files.length; j++) { 
     var input = fs.readFileSync(files[i]); 
     zip.addFile(csvFileName, input, '', 0644); 
     } 

     zip.writeZip(zipFileName); 

     return zipFileName; 

    } 

    getTableName() 
     .then(getData) 
     .then(createFile) 
     .then(function(zipFile) { 
     resolve(zipFile); 
     }) 
     .catch(function(err) { 
     resolve(err); 
     }); 

    }); 
} 

答えて

4

あなたはgetDataは約束を返すように、(両方のインスタンスで)Promise.all(...).then(...)の結果をreturnする必要があります。

また、問題の原因ではありませんが、promise constructor antipatternを使用しています。

return new Promise(function(resolve, reject) {ラッパーを削除し、ちょうどこのように返す:

return getTableName().then(getData) 

... resolve

+0

returnしたいです迅速な返信をありがとう、このアプローチは素晴らしい仕事です。 –

1

への呼び出しを残してあなたはおそらくちょうどチェーンPromise.all

var getData = function(runningResult) { 
     var promises = []; 

     if(data.date_start && data.date_end) { 
     // grab within range 

     for(var i = 0; i < runningResult.table.length; i++) { 
      promises.push(
      knexHistory(runningResult.table[i].table) 
       .select('created', 'data_value as value', 'unit') 
       .whereBetween('created', [data.date_start, data.date_end]) 
      ); 
     } 

     // *** the chain moves on to createFile() before this data is passed along 
     return Promise.all(promises).then(function(data) { 
      console.dir('inside promises.all'); 
      console.dir(data); 
      runningResult.data = data; 
      return runningResult; 
     }); 

     } else { 
     // grab all 
     for(var i = 0; i < runningResult.table.length; i++) { 
      promises.push(
      knexHistory(runningResult.table[i].table) 
       .select('created', 'data_value as value', 'unit') 
      ); 
     } 

     // *** the chain moves on to createFile() before this data is passed along 
     return Promise.all(promises).then(function(data) { 
      console.dir('inside promises.all'); 
      console.dir(data); 
      runningResult.data = data; 
      return runningResult; 
     }); 
     } 
    } 
関連する問題