先看一段例程:

//-------------------------------
// 用于创建目录
//-------------------------------
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:\Users\horn1\Desktop\node.js\58-理想论坛爬虫1.04>node nimble.js
First Job
准备创建目录
目录infos(2018-04-25 6_33_19)已创建
Second Job
Third Job
Forth Job

但它有时也这样运行:

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

C:\Users\horn1\Desktop\node.js\58-理想论坛爬虫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:\Users\horn1\Desktop\node.js\58-理想论坛爬虫1.04>node async.js
First job
准备创建目录
Second job
Third job
Forth job
目录infos(2018-04-25 6_43_21)已创建

C:\Users\horn1\Desktop\node.js\58-理想论坛爬虫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分

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

  1. NodeJs使用async让代码按顺序串行执行

    描述 由于nodejs中的函数调用都是异步执行的,而笔者在工程开发中函数A需要四五个参数,而这四五个参数值都是通过函数调用获得,因此按顺序写代码时,执行到函数A时,往往函数A需要的参数值因为参数的异步 ...

  2. vue使用技巧:Promise + async + await 解决组件间串行编程问题

    业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...

  3. 【Nodejs】使用nimble串行化回调任务

    nodejs的nimble模块可以使我们对回调任务进行串行化,它需要先安装 #npm install nimble 用法也方便,示例代码如下: //========================== ...

  4. async/await实现图片的串行、并行加载

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. nodejs进阶(7)—async异步流程控制

    Async介绍 Async是一个流程控制工具包,提供了直接而强大的异步功能.基于Javascript为Node.js设计,同时也可以直接在浏览器中使用. Async提供了大约20个函数,包括常用的 m ...

  6. 进程与程序 并行 并发 串行 阻塞 join函数

    进程是正在运行的程序,程序是程序员编写的一对代码,也就是一堆字符,当这堆代码被系统加载到内存并执行,就有了进程. (需要注意的是:一个程序是可以产生多个程序,就像我们可以同时运行多个QQ程序一样,会形 ...

  7. async/await 里的并行和串行

    我们在使用 async/await 语法时,有时会这样用: function getName () { return new Promise((resolve, reject)=>{ setTi ...

  8. nodejs异步调用async

    犹豫nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦,async的流程控制就是为了简化这些操作var async = require('async'); 1.serie ...

  9. java 保证程序安全退出

    以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...

随机推荐

  1. codevs 2596 售货员的难题

    2596 售货员的难题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某乡有n个村庄(1<n<=15),有一个售货 ...

  2. centos7安装redis-4.0.1集群

    试验机操作系统:CentOS Linux release 7.2.1511 (Core) 本文的目的是教会大家快速搭建redis集群,完了再深入学习. 试问如果不上手试验,看的资料再多有个毛用? 下载 ...

  3. spring---aop(8)---Spring AOP中optimize

    写在前面 optimize是ProxyConfig的属性.意思为 是否对生产代理策略使用优化. public class ProxyConfig implements Serializable { p ...

  4. macbook pro 开发帮助

    java安装目录 /Library/java/JavaVirtualMachines/ 设置快捷目录 vim .bash_profile 文件中追加一下信息:export dirname=目录路径 重 ...

  5. 客户端程序获取自己的ip、isp、地理位置等信息

    @ 比如说你需要收集用户信息,又或者要通过这些信息让用户登陆合适的服务器(北京联通用户登陆北京联通服务器). @ 淘宝和新浪都提供了类似的API,你只需要发送一个http请求,它就返回一个json格式 ...

  6. HTML5学习笔记4

    10.表单元素表单元素用于获取用户的输入数据form 表示HTML表单属性:    action 表示表单提交的页面    method 表示表单提交的请求方式:有POST和GET两种,默认GET(P ...

  7. 手动为Android 4.x 手机加入�自己的根证书(CA 证书)

    首先看Android 4.x 系统的证书存放位置: AOSP Android系统中CA证书文件的位置在:/ system/etc/security/cacerts/一系列的以数字命名的.0文件 方法一 ...

  8. 图片未完成加载显示loading

    <html> <title>js图片未加载完显示loading效果</title> <body> <style> img{float:lef ...

  9. go test

    testing 是go中自动测试的包, 直接import就可以使用, 使用时需要注意以下规范 执行测试函数的文件必须以 _test.go 结尾, 注意下划线 单元测试函数名必须以 Test 开头, 并 ...

  10. C#编程(九)----------控制台I/O

    原文链接:http://blog.csdn.net/shanyongxu/article/details/46454985 控制台I/O 可以使用Console.ReadLine()方法从控制台中读取 ...