分享:异步批量操作数据库的处理
发布于 11 年前 作者 duyinghua 11066 次浏览 最后一次编辑是 8 年前

最近写数据库批量插入数据的时候遇到了一个异步编程之痛的问题,就是数据库操作都是异步回调的,那么就没有办法用for循环来操作了,思考了一下,看来只能利用迭代循环了,举例分享一下,希望高手提提意见,小白小心一下。

exports.saveBatch = function saveBatch(basicInfos, callback) {
    executeFunc(basicInfos, 0, [], callback);
}
function executeFunc(basicInfos, count, errs, callback) {//errs是个错误信息收集器,最后统一返回错误信息集合
    if (count == basicInfos.length) {
        callback(errs);
    } else {
        basicInfos[count].save(function (err) {
            count++;
            err && errs.push(err.message);
            executeFunc(basicInfos, count, errs, callback);
        });
    }
}
14 回复

你可以考虑用async或Jscex

使用外围标记,在for循环中使用代码段标记判断即可,形如:

    var flag = 0;
    var datas = [.........................];
    for(var i =0; i < datas.length; i++){
        save(datas[i],function(){
            if(i == ++flag){
                callback();
            }
        });
    }

这个不错

这个也是有问题的,如果save的 callback被立即执行,callback将不被执行

数据都不依赖,这样串行执行没意义啊。

@chloe have a try ok? 这里的比较微妙之处就是括号的用法

@a272121742

考虑下面这样的情况 `

function save(data,callback){

console.log(data); callback(); }

function callback(){ console.log(“callback”); } var flag = 0; var datas = [1]; for(var i =0; i < datas.length; i++){ save(datas[i],function(){ if(i == ++flag){ callback(); } }); }

`这上面写法会导致callback不能被调用

请关注 async.eachForSeries. 不知道有没拼写错误。

@chloe 书写错误,如果flag初始值为0,使用flag++判断,如果为1,使用++flag判断

这样的批量操作肯定对性能有很大影响,弄不好网络还给堵死了。最好是运用数据库提供的批量操作,比如说pipe,或者合并sql,批量执行。

能详细介绍下如何使用pipe吗?

@duyinghua 这个我也不太懂,只是感觉sql的客户端应该会提供这样的操作,你google搜搜吧,应该很多的。

理论上我是做了一个Pool,然后利用 process.nextTick,但是我处理的只是在数据库异步初始化时候把它变成同步。假如是针对每次操作,能就要用的event的操作。其实这个一个很大的问题。异步操作时nodejs 的特性,不好的地方就是在大架构逻辑操作的时候,逻辑的耦合会很不容易处理。

回到顶部