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;
});
}
}
我是相当新的承诺,并认为我能处理事情,但显然我没有。
以下代码旨在获取 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;
});
}
}