一个异步流程控制库:Async.js

简介: 【摘要】Node.js的异步编程方式有效提高了应用性能,然而回调地狱却让人望而生畏,Promise让我们告别回调函数;在实践过程中,却发现Promise并不完美;技术进步是无止境的,后来有了Async/Await,让我们能够写出阻塞式的异步处理代码,然而对于一些流程控制方面还是很难写出优雅的代码。async.js的出现,能够写出简单清晰的异步流程控制代码。本文主要介绍项目中的常用方法。

【摘要】Node.js的异步编程方式有效提高了应用性能,然而回调地狱却让人望而生畏,Promise让我们告别回调函数;在实践过程中,却发现Promise并不完美;技术进步是无止境的,后来有了Async/Await,让我们能够写出阻塞式的异步处理代码,然而对于一些流程控制方面还是很难写出优雅的代码。async.js的出现,能够写出简单清晰的异步流程控制代码。本文主要介绍项目中的常用方法。

项目官网:caolan.github.io/async/index…

网络异常,图片无法展示
|

简介

Async是一个流程控制工具包,提供了直接而强大的异步功能。基于Javascript为NodeJs设计,也可以直接在浏览器中使用。

在官方文档中,async.js的功能分为三个部分:流程控制、集合处理、工具。包括常用的 map, reduce, filter, forEach 等,异步流程控制模式包括:串行(series)并行(parallel)瀑布(waterfall)等。

常用方法介绍

parallel:多个任务并发执行

用于并行执行多个方法,所有传入的方法都是立即执行,方法之间没有数据传递。传递给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。

  • 调用方式:parallel(tasks, [callback])
  • 参数:
  • tasks:需要执行多个方法。tasks可以以数组形式传入,也可以以object对象形式传入。每个方法都要一个回调方法callback(err, result),回调方法需要提供一个err参数或是result参数。当发生错误时(即:err参数存在时),所有的方法停止执行,未执行完的方法将不会被传递至最终回调方法中。
  • callback(err, results):可选的最终回调方法。出错时,tasks中抛出的错误将在此方法中捕获,错误被传入err参数。不出错时,tasks中回调结果将被写入results参数中,以数据或对象形式提供。
  • 示例:
// 此段代码实现在传入uid,获取用户信息、用户文章列表、文章评论信息
Async.parallel({
    account: callback => {
        accountController.getByUid(keyword, callback);
    },
    articles: callback => {
        articlesController.getByUid(keyword, callback);
    },
    comments: callback => {
        commentsController.getByAid(keyword, callback);
    }
},
(error, results) => {
    console.log(results)
});
  • 输出结果:
{
    "account":{
        "hash":"0x5eea3620415c6661912bb1c82aa7895f728e6258ea9d1b62f11acff7330f5cf1",
        "timestamp"1546076450,
        "name":"devpoint",
    },
    "articles":[],
    "comments":null
}

series:多个任务依次执行

用于依次执行多个方法,一个方法执行完毕后才会进入下一方法,方法之间没有数据传递。

  • 调用方式:series(tasks, [callback])
  • 参数:
  • tasks:需要执行多个方法。tasks可以以数组形式传入,也可以以object对象形式传入。每个方法都要一个回调方法callback(err, result),用于处理错误或进入下一方法。当发生错误时(即:err参数存在时),其后的方法会跳过,错误被传入最终回调方法中。
  • callback(err, results):可选的最终回调方法。出错时,tasks中抛出的错误将在此方法中捕获,错误被传入err参数。不出错时,tasks中回调结果将被写入results参数中,以数据或对象形式提供。
  • 示例
//以数组形式传入需要执行的多个方法
Async.series(
    [
        callback => {
            // 执行一些操作后,callback进入下一方法
            callback(null, "one");
        },
        callback => {
            // 执行一些操作后,callback进入可选的最终回调方法
            callback(null, "two");
        }
    ],
    // 可选的最终回调
    (err, results) => {
        // 当tasks中的任一方法发生错误,即回调形式为callback('错误信息')时,错误将被传递给err参数,未发生错误err参数为空
        // results中为数组中两个方法的结果数组:['one', 'two']
    }
);
//以object对象形式传入需要执行的多个方法
async.series(
    {
        one: callback => {
            // 执行一些操作后,callback进入下一方法
            callback(null, 1);
        },
        two: callback => {
            // 执行一些操作后,callback进入可选的最终回调方法
            callback(null, 2);
        }
    },
    (err, results) => {
        // 当tasks中的任一方法发生错误,即回调形式为callback('错误信息')时,错误将被传递给err参数,未发生错误err参数为空
        // results中为数组中两个方法的结果对象:{one: 1, two: 2}
    }
);

waterfall:多个函数依次执行,且前一个的输出为后一个的输入

series相似,按顺序依次执行多个函数。不同之处,每一个函数产生的值,都将传给下一个函数,如果中途出错,后面的函数将不会执行,错误信息以及之前产生的结果,都传给waterfall最终的callback。

这个函数的名字为waterfall(瀑布),可以想象瀑布从上到下,承上启下,有点类似于linux中的pipes。 注意该函数不支持object格式的tasks。

  • 调用方式:waterfall(tasks, [callback])
  • 参数:
  • tasks:需要执行多个方法。tasks只能以数组形式传入。每个方法都要一个回调方法callback(err, result1, result2, ...),用于处理错误或进入下一方法。当发生错误时(即:err参数存在时),其后的方法会跳过,错误被传入最终回调方法中。无错误时回调参数result1, result2……将做为下一方法的输入参数
  • callback(err, results):可选的最终回调方法。出错时,tasks中抛出的错误将在此方法中捕获,错误被传入err参数。不出错时,tasks中回调结果results为最后一个方法的回调结果。
  • 示例:
Async.waterfall(
    [
        callback => {
            callback(null, "one", "two");
        },
        (arg1, arg2, callback) => {
            console.log("arg1=" + arg1 + ";arg2=" + arg2);
            callback(null, "three");
        },
        (arg1, callback) => {
            console.log("arg1=" + arg1);
            callback(null, "done");
        }
    ],
    (err, result) => {
        //执行的任务中方法回调err参数时,将被传递至本方法的err参数
        //参数result为最后一个方法的回调结果'done'
        console.log(result);
    }
);

结果:

arg1=one;arg2=two
arg1=three
done

mapSeries:迭代执行,一个完了才执行下一个

迭代执行。将coll(是一个数组,不能是一个json对象)中的每一项依次拿给iterator去执行,执行结果传给最后的callback

  • 调用方式:async.mapSeries(coll, iteratee, [callback])
  • 参数:
  • coll:迭代的集合
  • iteratee:迭代方法
  • callback(err, results):可选的最终回调方法。
  • 示例:
Async.mapSeries(
    [1, 2, 3, 4],
    (node, callback) => {
        callback(null, node + 1);
    },
    (err, results) => {
        console.log(results);
    }
);

结果:[ 2, 3, 4, 5 ]

项目地址:github.com/caolan/asyn…


相关文章
|
2月前
|
JavaScript 前端开发 Python
用python执行js代码:PyExecJS库
文章讲述了如何使用PyExecJS库在Python环境中执行JavaScript代码,并提供了安装指南和示例代码。
109 1
用python执行js代码:PyExecJS库
|
2月前
|
JavaScript 前端开发
JavaScript基础知识-流程控制之while循环
这篇文章介绍了JavaScript中的while循环和do...while循环的基础知识,并通过一个实际案例演示了如何使用while循环计算投资增长到特定金额所需的年数。
50 2
JavaScript基础知识-流程控制之while循环
|
10天前
|
JavaScript 前端开发 搜索推荐
Moment.js、Day.js、Miment,日期时间库怎么选?
【10月更文挑战第29天】如果你需要一个功能强大、插件丰富的日期时间库,并且对性能要求不是特别苛刻,Moment.js是一个不错的选择;如果你追求极致的轻量级和高性能,那么Day.js可能更适合你;而如果你有一些特定的日期时间处理需求,并且希望在性能和功能之间取得平衡,Miment也是可以考虑的。
|
15天前
|
存储 JavaScript 前端开发
decimal.js库的安装和使用方法
【10月更文挑战第24天】decimal.js 是一个非常实用的高精度计算库,通过合理的安装和使用,可以在 JavaScript 中实现精确的数值计算和处理。你可以根据具体的需求和项目情况,灵活运用该库来解决数字精度丢失的问题。
|
1月前
|
JavaScript 前端开发 开发者
jQuery:JavaScript库的瑰宝
jQuery:JavaScript库的瑰宝
41 3
|
2月前
|
JavaScript 前端开发
JavaScript基础知识-流程控制之for循环
这篇文章讲解了JavaScript中的for循环的基础知识,并通过一个实例演示了如何使用for循环来找出所有的三位水仙花数。
47 6
JavaScript基础知识-流程控制之for循环
|
2月前
|
JavaScript 前端开发
常用的 JavaScript 框架和库
常用的 JavaScript 框架和库
123 6
|
29天前
|
JavaScript 前端开发 API
深入了解jQuery:快速、高效的JavaScript库
【10月更文挑战第11天深入了解jQuery:快速、高效的JavaScript库
10 0
|
2月前
|
移动开发 JavaScript 数据可视化
|
1月前
|
缓存 JavaScript 前端开发
JavaScript 库
JavaScript 库
19 0