关于async.map 中执行数据库操作的执行顺序问题
发布于 8 年前 作者 cheergoh 4926 次浏览 来自 问答

错误.png 如图,async.map 中的maparr是一批需要入库的数据,我在map内部执行了数据入库的操作,按理说应该是按照map的数组参数依次执行,即前面一个数组元素入库了才会执行maparr的下一个值的入库,但实际运行结果却是map全部遍历完了才会依次执行数据库操作,而且(数据库操作)每次执行到maparr的第二个元素就会报错(Error: Unknown prepared statement handler (2) given to mysqld_stmt_execute),不知道是为什么?求大神帮忙看一下,谢谢。

13 回复

我在map内部执行了数据入库的操作,按理说应该是按照map的数组参数依次执行,即前面一个数组元素入库了才会执行maparr的下一个值的入库,但实际运行结果却是map全部遍历完了才会依次执行数据库操作

map 对元素处理的顺序没有保证的,他只保证当所有的元素处理完毕之后会去调用最后的 function(err, results) {} 并把得到的结果传给他。 另外那个 mysql 的问题就不清楚了,你用了什么库,表建了没有?

@IchiNiNiIchi 哦 ,我理解错了,而且是异步执行的。数据库用的是mysql,引用的是“mysql2”,表也有的,看打印日志,但总是会报这个奇怪的错误,如果我的maparr中只有1条数据就正常执行,超过1条就会报上面的错误。

map循环是非异步,读取数据库涉及到磁盘i/o,才是异步的。而且楼上说的不错,循环顺序是不确定的,只能保证最终结果和map一一对应

@DevinXian 嗯 这个我清楚了 ,但为什么数据库的操作是等到map遍历完毕后才会执行呢?而且遍历的数据超过两条就会报上面的错误,是我写法又问题吗?

@cheergoh 那你可以试试 async.mapSeries,如果你不关心最后的 results 的话,也可以用 async.eachSeries,这些都是一个元素一个元素处理的。

@cheergoh 不是数据库的操作等到遍历完才执行,而是数据库操作完成需要一段时间,在这段时间里面 map 已经遍历完了。至于不能超过两条,应该是 mysql prepare 不能同时处理两个吧。

@IchiNiNiIchi 我还没在nodejs里面使用过prepare statements;好像记得prepare应该是一次,然后都是execute吧…

用的哪个模块?

@DevinXian 楼主没有给出他的 sql 语句,不知道他到底执行了什么操作。

@IchiNiNiIchi @DevinXian 用的是mysql2,果然是不能同时处理多个(不知道是不是我写的又问题),我直接connection.execute之后就可以了。现在发现了一个新问题,插入1000条数据需要30秒,时间好长啊,有办法快点吗?我要导的数据量是几万几十万的。

这个是prepare里面的实现 connection.prepare(sql, function (err, statement) { statement.execute(params, function (err, rows, columns) { callback(err, rows, columns); }); statement.close(); });

@IchiNiNiIchi 就是执行了向一个表的insert 没复杂操作

@cheergoh mysql prepare statements是支持batchExecute,你看看mysql2有没有写驱动接口,没有那就…~

map 不会顺序执行 mapSeries 才会顺序执行

回到顶部