Node.js的异步编程库async

Stella981
• 阅读 513

官方文档:http://caolan.github.io/async/docs.html

async包含了几个部分,Controlflow(异步流程处理),Utils(工具类),Collections(一些异步数据结构的操作(map objects arrays ))

流程控制函数:(control flow)

这些函数都是调用后立刻返回,不阻塞

1.series(tasks, callback)多个函数依次执行,之间没有数据交互

执行结果保存在series函数额参数 callback(err,res) 的res中,如果其中某个函数调用了callback()并且都一个参数不为null 那么将会立即调用最终的callback 中断未执行的剩余函数

async.series([
    function(callback) {
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback) {
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results) {
    // results is now equal to ['one', 'two']
});

async.series({
    one: function(callback) {
        setTimeout(function() {
            callback(null, 1);
        }, 200);
    },
    two: function(callback){
        setTimeout(function() {
            callback(null, 2);
        }, 100);
    }
}, function(err, results) {
    // results is now equal to: {one: 1, two: 2}
});

2.parallel(tasks, callback)立即并行执行所有函数

最终callback的结果顺序就是函数的在数组中的顺序,

如果某个函数出发了错误,那么最终的callback会被立即调用结果包含已经执行完了的函数的结果,剩余的callback将依然会调用,但最终的calback不会被调用,但结果会传到最终callback的参数依然有效,如:

async.parallel([
    function (callback) {
        // do some stuff ...
        callback(1111, 'one');
        console.log("1111111");
    },
    function (callback) {
        // do some more stuff ...
    
        callback(null, 'two');

        console.log("22222222222222");
    }
],
// optional callback
function (err, results) {
    // results is now equal to ['one', 'two']
    console.log(JSON.stringify(results));
    sss = results;

});

setTimeout(function(){

console.log(JSON.stringify(sss)); /// 打印最终结果
},1000);

/*
输出:
["one"]
1111111
2222222222
["one","two"]
*/

3.waterfall(tasks, callback) (多个函数依次执行,且前一个的输出为后一个的输入)

如果某个函数触发了错误,那么下个函数不会被执行,并且会把错误传递给最终callback,最终callback函数会被立刻调用,

/*
Runs the tasks array of functions in series, each passing their 
results to the next in the array. However, if any of the tasks pass 
an error to their own callback, the next function is not executed, and 
the main callback is immediately called with the error.
*/


async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
        // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});

4. auto(tasks, callback) ( 多个函数有依赖关系, 有的并行执行, 有的依次执行)

/*
这里假设我要写一个程序,它要完成以下几件事:
1.从某处取得数据
2.在硬盘上建立一个新的目录
3.将数据写入到目录下某文件
4.发送邮件,将文件以附件形式发送给其它人。
分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。
*/

async.auto({
    GetData: function (callback) {
        console.log('.....GetData');
        callback(null, "GetData");

    }, CreateDir: function (callback) {
        console.log('.....CreateDir');
        
        callback(null, 'CreateDir');
    },
    WriteToFile: ["GetData", "CreateDir", function (callback, res) {
            setTimeout(function () {
                console.log('.....WriteToFile ' + JSON.stringify(res));
                callback(null, 'WriteToFile');
            }, 300);
        
        }],
    
    SendEmail: ["WriteToFile", function (callback, res) {
            console.log('.....SendEmail ', res);
            callback(null, "111");

        }]
}, 
        
function (err, res) {
    
    console.log('.....done ', res);

});

5. whilst(test, fn, callback)  异步的while循环

先执行test 如果返回true 那么调用fn,fn调用错误,或者test返回false。那么立刻调用最终callback

var count = 0;
async.whilst(
    function () { return count < 5; },
    function (callback) {
        count++;
        setTimeout(function () {
            console.log(count);
            callback(null, count);
        }, 200);
    },
    function (err, n) {
        console.log("  res " +(count));
    }
);
console.log("............");  

6.queue(worker, number) 把任务添加到一个队列,通过worker来调用执行任务,parallel执行worker,number允许 worker并行的数量默认是1,也就是依次执行,此外还有一些事件

/*
Creates a queue object with the specified concurrency. 
Tasks added to the queue are processed in parallel 
(up to the concurrency limit). If all workers are in progress, 
the task is queued until one becomes available. Once a worker 
completes a task, that task's callback is called.
*/

 
var q = async.queue(function (task, callback) {
    console.log('start to process task: ' + task.name);
    callback();

}, 3);

// assign a callback
q.drain = function () { // 所有任务执行完调用
    console.log('all items have been processed');
};

// add some items to the queue
q.push({ name: '111111111' }, function (err) {
    setTimeout(function () {
        console.log('finished processing 11111111');
    }, 1000);

});


q.push({ name: '2222222222' }, function (err) { // 
    setTimeout(function () {
        console.log('finished processing 22222222222');
    }, 2000);
});

// add some items to the queue (batch-wise)  //添加多个任务
q.push([{ name: 'baz' }, { name: 'bay' }, { name: 'bax' }], function (err) {
    console.log('finished processing item');
});

// add some items to the front of the queue
q.unshift({ name: 'bar111' }, function (err) { //添加任务到队列之前
    console.log('finished processing bar111');
});


setTimeout(function () {
    q.unshift({ name: '3333333333' }, function (err) {
        console.log('finished processing 444444444444');
    });


}, 100);

q.saturated = function () { //worker数量用完时调用
    console. log('all workers to be used');
}

q.empty = function () {//最后一个任务提交worker时调用
    console. log('no more tasks wating');
}



console.log("............");
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这