【Nodejs】nimble或async并不能保证程序串行执行,回调是回避不了的坑

先看一段例程:

//-------------------------------
// 用于创建目录
//-------------------------------
function createFolder(){
    console.log('准备创建目录');

    folder='infos('+currDateTime()+")";
    var fs=require('fs');
    fs.mkdir('./'+folder,function(err){
        if(err){
            console.log("目录"+folder+"已经存在");
        }else{
            console.log("目录"+folder+"已创建");
        }
    });
}

//-------------------------------
// 入口函数
// start:起始页,从1开始
// end:终止页,>start
//-------------------------------
function main(start,end){
    var flow=require('nimble');

    flow.series([
        function(callback){
            setTimeout(function(){ 
                console.log('First Job')
                createFolder();
                callback();
            },1);
        },

        function(callback){
            setTimeout(function(){ 
                console.log('Second Job')
                callback();
            },1);
        },

        function(callback){
            setTimeout(function(){ 
                console.log('Third Job')

                
                callback();
            },1);
        },

        function(callback){
            setTimeout(function(){ 
                console.log('Forth Job')

                callback();
            },1);
        },
    ]);
}

//--------------------------------------
// 通用函数,返回当前日期时间
//--------------------------------------
function currDateTime() {
    var date = new Date();
    var seperator1 = "-";
    var seperator2 = "_";
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate =date.getFullYear() + seperator1 + month + seperator1 + strDate
            + " " + date.getHours() + seperator2 + date.getMinutes()
            + seperator2 + date.getSeconds();
    return currentdate;
}

// 开始
main(1,10);

原以为它会这样运行:

C:Usershorn1Desktop
ode.js58-理想论坛爬虫1.04>node nimble.js
First Job
准备创建目录
目录infos(2018-04-25 6_33_19)已创建
Second Job
Third Job
Forth Job

但它有时也这样运行:

C:Usershorn1Desktop
ode.js58-理想论坛爬虫1.04>node nimble.js
First Job
准备创建目录
Second Job
目录infos(2018-04-25 6_34_3)已创建
Third Job
Forth Job

C:Usershorn1Desktop
ode.js58-理想论坛爬虫1.04>node nimble.js
First Job
准备创建目录
Second Job
目录infos(2018-04-25 6_34_9)已创建
Third Job
Forth Job

很明显,如果第二个任务是需要第一个任务的结果比如是folder的生成,那么运行中一定会出现异常,因为未必目录会在第二个任务执行前准备好。

下面让我们看看async的代码:

//-------------------------------
// 用于创建目录
//-------------------------------
function createFolder(){
    console.log('准备创建目录');

    folder='infos('+currDateTime()+")";
    var fs=require('fs');
    fs.mkdir('./'+folder,function(err){
        if(err){
            console.log("目录"+folder+"已经存在");
        }else{
            console.log("目录"+folder+"已创建");
        }
    });
}

//-------------------------------
// 入口函数
// start:起始页,从1开始
// end:终止页,>start
//-------------------------------
function main(start,end){
    var async=require('async');

    async.series([
        function(done){
            console.log('First job');
            createFolder();
            done();
        },    
        function(done){
            console.log('Second job');
            done();
        },
        function(done){
            console.log('Third job');
            done();
        },
        function(done){
            console.log('Forth job');
            done();
        },    
    ]);
}

//--------------------------------------
// 通用函数,返回当前日期时间
//--------------------------------------
function currDateTime() {
    var date = new Date();
    var seperator1 = "-";
    var seperator2 = "_";
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate =date.getFullYear() + seperator1 + month + seperator1 + strDate
            + " " + date.getHours() + seperator2 + date.getMinutes()
            + seperator2 + date.getSeconds();
    return currentdate;
}

// 开始
main(1,10);

其运行结果有:

C:Usershorn1Desktop
ode.js58-理想论坛爬虫1.04>node async.js
First job
准备创建目录
Second job
Third job
Forth job
目录infos(2018-04-25 6_43_21)已创建

C:Usershorn1Desktop
ode.js58-理想论坛爬虫1.04>node async.js
First job
准备创建目录
Second job
Third job
Forth job
目录infos(2018-04-25 6_43_24)已创建

很明显,没有延时的帮助,四个任务都处理了,目录才创建完成,如果三个任务都依赖目录,那么异常就出现了。

之前在有些论坛上看到有人以程序里有二十多个回调括号大括号自矜,当时觉得这种方式程序并不好读好修改,现在看他也是不得已而为之。

Nodejs程序里回调始终是坑。

2018年4月25日06点53分

原文地址:https://www.cnblogs.com/heyang78/p/8939111.html