【发布时间】:2018-06-02 05:52:32
【问题描述】:
我对 node 还很陌生,我一直在学习和处理异步/承诺。现在我正在尝试创建一个从数据库(例如 10K 行)进行插入的进程,调用一个转换一列的 Web 服务,然后为修改后的数据进行插入。
所以,我做了一个 Oracle SQL 查询,并为结果做了一个 foreach:
let counter = 0;
var binds = [];
res.rows.forEach((row) => {
var original_data = row[0];
Transform(original_data).then(new_data => {
counter++;
binds.push([original_data,new_data]);
if (counter % 1000 === 0){
console.log(`1K rows`);
doInserts(binds);
binds = [];
}
});
});
我每 1000 行调用一次doInserts,所以我没有在 Oracle 上打开很多事务。
Transform 函数调用一个 Web 服务,该服务使用我需要的值进行解析。
function Transform(value){
return new Promise(function(resolve, reject){
var requestPath = `http://localhost:3000/transform/${value}`;
var req = request.get(requestPath, function(err, response, body){
if (!err && response.statusCode == 200){
resolve(body);
}else{
reject("API didn't respond.");
}
}).end();
});
}
但是,当 foreach 有 10K 行时,这会阻塞 Web 服务(我使用 request 库进行连接)。我在想,foreach 不会一次同步进行一次转换。
这可能是我不知道很多节点、异步、承诺......但我很困惑。有人可以帮忙吗?
【问题讨论】:
-
哇,从哪里开始? :) 1)
res.rows来自哪里? 2) 你的forEach关闭res.rows是一个同步循环做异步工作,通常不是一个好主意。 3)似乎您的转换在本地主机上。你可以调用一个函数来完成这项工作吗? 4) 获取行的逻辑和执行插入的逻辑看起来有风险。如果中途失败了怎么办?如果这是您想要的批量大小,为什么不一次只获取 1000 行 - 那么您只需要确保您有办法查询下一个“未处理”集。 5)doInserts是如何实现的? -
如果要插入很多行,请确保使用 executeMany() 并且不要进行单行插入。并使用绑定。
标签: javascript node.js