2017-04-12 56 views
1

我是相当新的承诺,并认为我有处理事情,但显然我没有。Promise Chain Breaks w/.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

您需要returnPromise.all(...).then(...)的结果(在这两种情况),从而使getData返回一个承诺。

而且,是的,您正在使用promise constructor antipattern,虽然它不是问题的原因。

取出return new Promise(function(resolve, reject) {包装,只是返回是这样的:

return getTableName().then(getData) 

...离开了呼叫resolve

+0

感谢您的快速回复,这种方法运作良好。 –

1

你可能只是想return链式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; 
     }); 
     } 
    }