Promise Chain Breaks w/ .all()

Promise Chain Breaks w/ .all()

我是相当新的承诺,并认为我能处理事情,但显然我没有。

以下代码旨在获取 X 个 table 名称 (getTableName()),将它们传递给 getData() 并遍历每个 table 以获取数据。然后我调用 Promise.all() 来解决这些问题并尝试将数据传递到链中的下一个 link (createFile()) 但是 Promise.all() 在它移动到创建文件()。

这是"antipattern"回来咬我的例子吗?如果是这样,你能建议我应该如何重组才能完成我打算做的事情吗?

谢谢!

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

  });
}

您需要 return Promise.all(...).then(...) 的结果(在两种情况下),以便 getData return 是一个承诺。

而且,是的,您正在使用 promise constructor antipattern,尽管这不是问题的原因。

删除 return new Promise(function(resolve, reject) { 包装器,然后 return 像这样:

return getTableName().then(getData)

...省略对 resolve

的调用

您可能只想 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;
        });
      }
    }