async 订阅
Async
信息
操作系统
未知
开发语言
开源协议
未知
Async
This plugin allows to easily code very long-lasting loops in an asynchronous way to avoid losing the browser responsiveness.
收起全文
精华内容
下载资源
问答
  • async

    千次阅读 2019-08-07 22:41:00
    async是什么? 说白了就是Generator的语法糖 把*换成async,把yield换成await罢了 //Generator写法 const gen = function* () { const f1 = yield readFile('/etc/fstab'); const f2 = yield readFile('/etc/...

    async是什么?
    说白了就是Generator的语法糖
    *换成async,把yield换成await罢了

    //Generator写法
    const gen = function* () {
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    
    //async写法
    const asyncReadFile = async function () {
      const f1 = await readFile('/etc/fstab');
      const f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    

    但他还是有可取之处的

    • 内置执行器
      async函数的执行像普通函数一样,只需要一个括号即可asyncReadFile()不像Generator,需要迭代器,调用next方法才可以执行

    • 更好的语义
      asyncawait,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

    • 更广的适用性。
      co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolvedPromise 对象)。

    • 返回值是 Promise
      async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

    进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

    基本用法

    async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

    下面是一个例子。

    async function getStockPriceByName(name) {
      const symbol = await getStockSymbol(name);
      const stockPrice = await getStockPrice(symbol);
      return stockPrice;
    }
    
    getStockPriceByName('goog').then(function (result) {
      console.log(result);
    });
    

    async 函数有多种使用形式。

    // 函数声明
    async function foo() {}
    
    // 函数表达式
    const foo = async function () {};
    
    // 对象的方法
    let obj = { async foo() {} };
    obj.foo().then(...)
    
    // Class 的方法
    class Storage {
      constructor() {
        this.cachePromise = caches.open('avatars');
      }
    
      async getAvatar(name) {
        const cache = await this.cachePromise;
        return cache.match(`/avatars/${name}.jpg`);
      }
    }
    
    const storage = new Storage();
    storage.getAvatar('jake').then(…);
    
    // 箭头函数
    const foo = async () => {};
    

    语法

    返回 Promise 对象

    async函数返回一个 Promise 对象。

    async函数内部return语句返回的值,会成为then方法回调函数的参数。

    async function f() {
      return 'hello world';
    }
    
    f().then(v => console.log(v))
    // "hello world"
    

    async函数内部抛出错误,会导致返回的 Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

    Promise 对象的状态变化

    async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

    下面是一个例子。

    async function getTitle(url) {
      let response = await fetch(url);
      let html = await response.text();
      return html.match(/<title>([\s\S]+)<\/title>/i)[1];
    }
    getTitle('https://tc39.github.io/ecma262/').then(console.log)
    // "ECMAScript 2017 Language Specification"
    

    上面代码中,函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法里面的console.log。

    await命令

    正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

    async function f() {
      // 等同于
      // return 123;
      return await 123;
    }
    
    f().then(v => console.log(v))
    // 123
    

    上面代码中,await命令的参数是数值123,这时等同于return 123。

    另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。

    class Sleep {
      constructor(timeout) {
        this.timeout = timeout;
      }
      then(resolve, reject) {
        const startTime = Date.now();
        setTimeout(
          () => resolve(Date.now() - startTime),
          this.timeout
        );
      }
    }
    
    (async () => {
      const sleepTime = await new Sleep(1000);
      console.log(sleepTime);
    })();
    // 1000
    

    上面代码中,await命令后面是一个Sleep对象的实例。这个实例不是 Promise 对象,但是因为定义了then方法,await会将其视为Promise处理。

    这个例子还演示了如何实现休眠效果。JavaScript 一直没有休眠的语法,但是借助await命令就可以让程序停顿指定的时间。

    function sleep(interval) {
      return new Promise(resolve => {
        setTimeout(resolve, interval);
      })
    }
    
    // 用法
    async function one2FiveInAsync() {
      for(let i = 1; i <= 5; i++) {
        console.log(i);
        await sleep(1000);
      }
    }
    
    one2FiveInAsync();
    

    其中for循环也会延缓执行
    await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

    任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

    async function f() {
      await Promise.reject('出错了');
      await Promise.resolve('hello world'); // 不会执行
    }
    

    有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。
    另一种方法是await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误。

    async function f() {
      await Promise.reject('出错了')
        .catch(e => console.log(e));
      return await Promise.resolve('hello world');
    }
    
    f()
    .then(v => console.log(v))
    // 出错了
    // hello world
    
    注意点
    • await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
    async function myFunction() {
      try {
        await somethingThatReturnsAPromise();
      } catch (err) {
        console.log(err);
      }
    }
    
    // 另一种写法
    
    async function myFunction() {
      await somethingThatReturnsAPromise()
      .catch(function (err) {
        console.log(err);
      });
    }
    
    • 多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
    // 写法一
    let [foo, bar] = await Promise.all([getFoo(), getBar()]);
    
    // 写法二
    let fooPromise = getFoo();
    let barPromise = getBar();
    let foo = await fooPromise;
    let bar = await barPromise;
    
    • await命令只能用在async函数之中,如果用在普通函数,就会报错。
      有时把普通函数改写成async函数也会报错。比如forEach
    function dbFuc(db) { //这里不需要 async
      let docs = [{}, {}, {}];
    
      // 可能得到错误结果
      docs.forEach(async function (doc) {
        await db.post(doc);
      });
    }
    

    上面代码可能不会正常工作,原因是这时三个db.post操作将是并发执行,也就是同时执行,而不是继发执行。正确的写法是采用for循环。

    async function dbFuc(db) {
      let docs = [{}, {}, {}];
    
      for (let doc of docs) {
        await db.post(doc);
      }
    }
    
    • async 函数可以保留运行堆栈。
    const a = () => {
      b().then(() => c());
    };
    

    上面代码中,函数a内部运行了一个异步任务b()。当b()运行的时候,函数a()不会中断,而是继续执行。等到b()运行结束,可能a()早就运行结束了,b()所在的上下文环境已经消失了。如果b()或c()报错,错误堆栈将不包括a()。

    现在将这个例子改成async函数。

    const a = async () => {
      await b();
      c();
    };
    
    async函数的实现原理

    将 Generator 函数和自动执行器,包装在一个函数里。
    手写await?

    function spawn(genF) {
      return new Promise(function(resolve, reject) {
        const gen = genF();
        function step(nextF) {
          let next;
          try {
            next = nextF();
          } catch(e) {
            return reject(e);
          }
          if(next.done) {
            return resolve(next.value);
          }
          Promise.resolve(next.value).then(function(v) {
            step(function() { return gen.next(v); });
          }, function(e) {
            step(function() { return gen.throw(e); });
          });
        }
        step(function() { return gen.next(undefined); });
      });
    }
    
    异步加载模块
    // awaiting.js
    const dynamic = import(someMission);
    const data = fetch(url);
    export const output = someProcess((await dynamic).default, await data);
    

    上面代码中,两个异步操作在输出的时候,都加上了await命令。只有等到异步操作完成,这个模块才会输出值。

    加载这个模块的写法如下。

    // usage.js
    import { output } from "./awaiting.js";
    function outputPlusValue(value) { return output + value }
    
    console.log(outputPlusValue(100));
    setTimeout(() => console.log(outputPlusValue(100), 1000);
    
    展开全文
  • EA Async在JVM中实现Async-Await方法。 它允许程序员以顺序的方式编写异步代码。 它在很大程度上受到.NET CLR上Async-Await的启发,有关更多信息,请参见进行。 谁应该使用它? 应该使用EA Async编写非阻塞异步...
  • Visual Studio C++ Opencv ASYNC
  • 网上async with和async for的中文资料比较少,我把PEP 492中的官方陈述翻译一下。 异步上下文管理器”async with” 异步上下文管理器指的是在enter和exit方法处能够暂停执行的上下文管理器。 为了实现这样的功能,...
  • 使用ES6新特性async await进行异步处理

    万次阅读 多人点赞 2018-07-12 15:56:30
    我们往往在项目中会遇到这样的业务需求,就是首先...那是相当恶心的,下面我就来讲一下如何使用ES6的新特性async await进行异步处理,使上述情况就好像写同步代码一样,首先我们先举个例子: 先写上json文件: cod...

    我们往往在项目中会遇到这样的业务需求,就是首先先进行一个ajax请求,然后再进行下一个ajax请求,而下一个请求需要使用上一个请求得到的数据,请求少了还好说,如果多了,就要一层一层的嵌套,就好像有点callback的写法了,那是相当恶心的,下面我就来讲一下如何使用ES6的新特性async await进行异步处理,使上述情况就好像写同步代码一样,首先我们先举个例子:
    先写上json文件:
    code.json:

    {
        "code":0,
        "msg":"成功"
    }
    

    person.json:

    {
        "code":0,
        "list":[
            {
                "id":1,
                "name":"唐僧"
            },
            {
                "id":2,
                "name":"孙悟空"
            },
            {
                "id":3,
                "name":"猪八戒"
            },
            {
                "id":4,
                "name":"沙僧"
            }
        ]
    }
    

    比如我们有两个请求,如下,这里用的axios:

     function getCode(){
          return axios.get('json/code.json');
      }
     function getlist(params){
          return axios.get('json/person.json',{params})
      }
    

    我们第二个请求获取列表的时候需要使用第一个请求得到的code值,只有code值为0时,才能请求,而且当做参数传进去,那么我们看一下常规的做法吧

    function getFinal(){
    	  console.log("我是getFinal函数")
          getCode().then(function(res){
             if(res.data.code == 0){
                   console.log(res.data.code);
                     var params = {
                          code:res.data.code
                      }
                   getlist(params).then(function(res){
                        if(res.data.code == 0){
                             console.log(res.data.list);
                           }
                       })
                    }
              })
          }
      getFinal();
    

    看结果
    这里写图片描述
    虽然结果出来了,可是这种写法真的挺难受的,下面来一个async await的写法

    async function getResult(){
                console.log("我是getResult函数")
                let code = await getCode();
                console.log(code.data.code);
                if(code.data.code == 0){
                    var params = {
                        code:code.data.code
                    }
                    let list = await getlist(params);
                    console.log(list.data.list);
                }
            }
    getResult();
    

    下面看结果
    这里写图片描述
    当然还剩最后一点,处理异常,可以加上try catch

    async function getResult(){
                console.log("我是getResult函数")
                try{
    				let code = await getCode();
    	            console.log(code.data.code);
    	            if(code.data.code == 0){
    	                var params = {
    	                    code:code.data.code
    	                }
    	                let list = await getlist(params);
    	                console.log(list.data.list);
    	            }
    			}catch(err){
    				console.log(err);
    			}
            }
    getResult();
    

    个人认为做vue项目的时候,如果对于异常没有特殊处理,可以不加try catch,因为打印出来的错误跟vue自己报的错误是一样的,而且还是黑的字体,不如醒目的红色来的痛快啊!当然如果要对错误进行特殊处理,那么就加上吧

    代码风格是不是简便了许多,而且异步代码变成了同步代码,下面我稍微讲一下后者写法的代码执行顺序

    首先在 function 前面加 async 用来说明这个函数是一个异步函数,当然,async是要和await配合使用的,第一个请求

    let code = await getCode();
    

    await 意思是等一下,等着getCode()这个函数执行完毕,得到值后再赋值给code,然后再用code的值进行下一步操作,就是这么简单!!!赶紧去改代码!!

    展开全文
  • 这是ETTask中的Async部分,它是一个单线程的Task
  • async function get(){ let res1 = await axios.get('http://127.0.0.1:2000/name.json') console.log(res1); let id = res1.data.data[0].id let res2 = await axios.get(`...
  • 此软件包提供AsyncAPI架构的所有版本。 安装 npm install @asyncapi/specs 用法 抓取特定的AsyncAPI版本: const asyncapi = require ( '@asyncapi/specs/schemas/2.0.0' ) ; // Do something with the schema. ...
  • 之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章。观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同步还有,setTimeout,...

    感谢内容提供者:金牛区吴迪软件开发工作室

    之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章。观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同步还有,setTimeout,Promise,async这些内容了然于胸,接下来让我们走入正题


    这是别的大佬博客里面的代码:

    async function async1() {
       console.log('async1 start')
       await async2()
       console.log('async1 end')
    }
    async function async2() {
       console.log('async2')
    }
    console.log('script start')
    setTimeout(() => {
    	console.log('setTimeout')
    },0)
    async1()
    new Promise((resolve) => {
    	console.log('promise1')
    	resolve()
    }).then(() => {
    	console.log('promise2')
    })
    console.log('script end')
    

    执行结果(不同浏览器执行结果可能不同,笔者用的谷歌):
    在这里插入图片描述

    PS:下面的关键点笔者都用加粗给朋友们圈起来了哦,请仔细观看

    笔者这时候开启了双屏模式,看它的这个代码的执行结果去猜它的规律,然后再看MDN文档,结果就一目了然了。
    我们现在一起来分析代码:
    在这里插入图片描述
    这只是定义了俩个异步函数(),并没有调用,所以暂时不用管。

    在这里插入图片描述
    这是同步的内容,所以会直接执行

    1.输出 script start

    在这里插入图片描述
    setTimeout是一个计时器,异步的,所以被扔到了任务队列里面,暂时不去管,我们只需要记住异步队列里面有他就可以。

    在这里插入图片描述
    调用了async1函数,会走入到这个函数里,我们先再看一下这个函数:
    PS:注意点:
    当调用async函数的时候会返回一个Promise对象
    。Promise对象是立即执行的,后面会详细介绍。

    在这里插入图片描述
    这时候会

    2.输出async1 start,

    而后到了await async2()
    这里需要注意一下,在async里遇到await它会使async函数暂停执行,执行完async里的await内容后将后续的内容扔入到浏览器的任务队列里面去。
    所以这里输出了async1 start后又

    3.输出了async2

    async2执行完毕之后又走回到调用了async1的位置。将async1没有执行的部分扔到了任务队列里面去。(现在任务队列里面有一个setTimeout和一个async1的后续内容)

    接下来又走到了Promise:
    在这里插入图片描述
    Promise是立即执行的,所以它会立即

    4.输出promise1。

    而后是执行了resolve。执行成功,执行成功的话会走入promise的.then方法里,可是它是异步的回调函数,所以会被丢入到任务队列里。(现在任务队列里面有一个setTimeout和一个async1的后续内容在加上promise的.then内容)

    最后走到了:
    在这里插入图片描述
    因为它是同步的,所以会直接执行。

    5.输出:script end

    前五个我们都分析完毕了,接下来到关键点了:
    现在异步队列中有三个任务分别是:

    • setTimeout
    • async1的后续内容
    • promise的.then内容

    这三个内容setTimeout会在最后执行,就好比css权重的优先级,大家固定记住就可以,setTimeout的优先级没有async和promise级别高(其实async和promise是一样的,因为调用async方法时就是返回一个promise对象
    而后async和promise的.then就看谁先进入到的任务队列里面,任务队列里面有先进先出的概念。所以结果很明显了,它们三个的输出顺序是:
    6.输出:async1 end
    7.输出:promise2
    8.输出:setTimeout

    在给朋友们随便写一个代码,大家一起猜一下执行结果会是什么:
    setTimeout(() => {
    	console.log('setTimeout')
    }, 0)
    console.log('t1')
    fetch('http://dict.qq.com')
     .then(function(response) {
       return response.json();
     })
     .then(function(myJson) {
       console.log('myJson');
     })
     .catch(function(err) {
     	console.log(err)
     })
    console.log('fetch zhi hou')
    async function async1() {
    	console.log('async1 start')
    	await async2()
    	console.log('async1 end')
    }
    async1()
    console.log('t2')
    new Promise((resolve) => {
    	console.log('promise')
    	resolve()
    }).then(() => {
    	console.log('promise.then')
    })
    console.log('t3')
    async function async2() {
    	console.log('async2')
    }
    console.log('t4')
    

    执行结果:
    在这里插入图片描述

    小总结:

    其实这个就是涉及了JavaScript的Event Loop【事件循环】
    在这里插入图片描述
    上图就是JS事件循环的全过程。

    执行全局Script同步代码,这些同步代码有一些是同步语句,有一些是异步语句(比如setTimeout等);
    全局Script代码执行完毕后,调用栈Stack会清空;
    从微队列microtask queue中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减1;
    继续取出位于队首的任务,放入调用栈Stack中执行,以此类推,直到直到把microtask queue中的所有任务都执行完毕。注意,如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行;
    microtask queue中的所有任务都执行完毕,此时microtask queue为空队列,调用栈Stack也为空;
    取出宏队列microtask queue中位于队首的任务,放入Stack中执行;
    执行完毕后,调用栈Stack为空;
    重复第3-7个步骤;
    重复第3-7个步骤;

    1.宏队列microtask一次只从队列中取一个任务执行,执行完后就去执行微任务队列中的任务;
    2.微任务队列中所有的任务都会被依次取出来执行,直道microtask queue为空;
    3.图中没有画UI rendering的节点,因为这个是由浏览器自行判断决定的,但是只要执行UI rendering,它的节点是在执行完所有的microtask之后,下一个macrotask之前,紧跟着执行UI render。

    展开全文
  • var async = require ( 'express-async' ) ; function mw1 ( req , res , next ) { } function mw2 ( req , res , next ) { } app . get ( '/' , async . parallel ( mw1 , mw2 ) ) ; 连续剧 var async = require ...
  • AsyncHttp demo

    2017-06-13 15:25:56
    AsyncHttp
  • Async.fi:Async.fi静态网站
  • Async 详解

    万次阅读 2019-03-24 10:45:54
    最终觉得还是async最靠谱。 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种常见流程的处理 集合处理:如何使用异步操作处理集合中的数据 工具类:几个常用的工具类 本文...

    一:流程控制

    为了适应异步编程,减少回调的嵌套,我尝试了很多库。最终觉得还是async最靠谱。

    地址:https://github.com/caolan/async

    Async的内容分为三部分:

    1. 流程控制:简化十种常见流程的处理
    2. 集合处理:如何使用异步操作处理集合中的数据
    3. 工具类:几个常用的工具类

    本文介绍其中最简单最常用的流程控制部分。

    由于nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦。Async的流程控制就是为了简化这些操作。

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

    有多个异步函数需要依次调用,一个完成之后才能执行下一个。各函数之间没有数据的交换,仅仅需要保证其执行顺序。这时可使用series。

    纯js代码:

    step1(function(err, v1) { step2(function(err, v2) { step3(function(err, v3) { // do somethig with the err or values v1/v2/v3 } } });

    从中可以看到这嵌套还是比较多深的,如果再多几步,会更深。在代码中忽略对了每一层err的处理,否则还都等加上 if(err) return callback(err),那就更麻烦了。

    对于这种情况,使用async来处理,就是这样的:

    var async = require('async') async.series([ step1, step2, step3 ], function(err, values) { // do somethig with the err or values v1/v2/v3 });

    可以看到代码简洁了很多,而且自动处理每个回调中的错误。当然,这里只给出来最最简单的例子,在实际中,我们常会在每个step中执行一些操作,这时可写成:

    var async = require('async') async.series([ function(cb) { step1(function(err,v1) { // do something with v1 cb(err, v1); }), function(cb) { step2(...) }, function(cb) { step3(...) } ], function(err, values) { // do somethig with the err or values v1/v2/v3 });

    该函数的详细解释为:

    1. 依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。
    2. 如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且将会立刻会将该error以及已经执行了的函数的结果,传给series中最后那个callback。
    3. 当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传给series最后的那个callback。
    4. 还可以json的形式来提供tasks。每一个属性都会被当作函数来执行,并且结果也会以json形式传给series最后的那个callback。这种方式可读性更高一些。

    具体例子可参考:https://github.com/freewind/async_demo/blob/master/series.js

    其代码中还包含了:

    1. 如果中间某个函数出错,series函数如何处理
    2. 如果某个函数传给回调的值为undefined, null, {}, []等,series如何处理

    另外还需要注意的是:多个series调用之间是不分先后的,因为series本身也是异步调用。

    2. parallel(tasks, [callback]) (多个函数并行执行)

    并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。

    如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。

    同时支持json形式的tasks,其最终callback的结果也为json形式。

    示例代码:

    async.parallel([ function(cb) { t.fire('a400', cb, 400) }, function(cb) { t.fire('a200', cb, 200) }, function(cb) { t.fire('a300', cb, 300) } ], function (err, results) { log('1.1 err: ', err); // -> undefined log('1.1 results: ', results); // ->[ 'a400', 'a200', 'a300' ] });

    中途出错的示例:

    async.parallel([ function(cb) { log('1.2.1: ', 'start'); t.fire('a400', cb, 400) }, // 该函数的值不会传给最终callback,但要占个位置 function(cb) { log('1.2.2: ', 'start'); t.err('e200', cb, 200) }, function(cb) { log('1.2.3: ', 'start'); t.fire('a100', cb, 100) } ], function(err, results) { log('1.2 err: ', err); // -> e200 log('1.2 results: ', results); // -> [ , undefined, 'a100' ] });

    以json形式传入tasks

    async.parallel({ a: function(cb) { t.fire('a400', cb, 400) }, b: function(cb) { t.fire('c300', cb, 300) } }, function(err, results) { log('1.3 err: ', err); // -> undefined log('1.3 results: ', results); // -> { b: 'c300', a: 'a400' } });

    更详细示例参见:https://github.com/freewind/async_demo/blob/master/parallel.js

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

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

    这个函数名为waterfall(瀑布),可以想像瀑布从上到下,中途冲过一层层突起的石头。注意,该函数不支持json格式的tasks。

    async.waterfall([ function(cb) { log('1.1.1: ', 'start'); cb(null, 3); }, function(n, cb) { log('1.1.2: ',n); t.inc(n, cb); }, function(n, cb) { log('1.1.3: ',n); t.fire(n*n, cb); } ], function (err, result) { log('1.1 err: ', err); // -> null log('1.1 result: ', result); // -> 16 });

    更详细示例参见:https://github.com/freewind/async_demo/blob/master/waterfall.js

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

    用来处理有依赖关系的多个任务的执行。比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。

    虽然我们可以使用async.parallel和async.series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。这时使用async.auto,则会事半功倍。

    如果有任务中途出错,则会把该错误传给最终callback,所有任务(包括已经执行完的)产生的数据将被忽略。

    这里假设我要写一个程序,它要完成以下几件事:

    1. 从某处取得数据
    2. 在硬盘上建立一个新的目录
    3. 将数据写入到目录下某文件
    4. 发送邮件,将文件以附件形式发送给其它人。

    分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。

    async.auto({ getData: function (callback) { setTimeout(function(){ console.log('1.1: got data'); callback(); }, 300); }, makeFolder: function (callback) { setTimeout(function(){ console.log('1.1: made folder'); callback(); }, 200); }, writeFile: ['getData', 'makeFolder', function(callback) { setTimeout(function(){ console.log('1.1: wrote file'); callback(null, 'myfile'); }, 300); }], emailFiles: ['writeFile', function(callback, results) { log('1.1: emailed file: ', results.writeFile); // -> myfile callback(null, results.writeFile); }] }, function(err, results) { log('1.1: err: ', err); // -> null log('1.1: results: ', results); // -> { makeFolder: undefined, // getData: undefined, // writeFile: 'myfile', // emailFiles: 'myfile' } });

    更多详细示例参见:https://github.com/freewind/async_demo/blob/master/auto.js

    5. whilst(test, fn, callback)(用可于异步调用的while)

    相当于while,但其中的异步调用将在完成后才会进行下一次循环。举例如下:

    var count1 = 0; async.whilst( function() { return count1 < 3 }, function(cb) { log('1.1 count: ', count1); count1++; setTimeout(cb, 1000); }, function(err) { // 3s have passed log('1.1 err: ', err); // -> undefined } );

    它相当于:

    try { whilst(test) { fn(); } callback(); } catch (err) { callback(err); }

    该函数的功能比较简单,条件变量通常定义在外面,可供每个函数访问。在循环中,异步调用时产生的值实际上被丢弃了,因为最后那个callback只能传入错误信息。

    另外,第二个函数fn需要能接受一个函数cb,这个cb最终必须被执行,用于表示出错或正常结束。

    更详细示例参见:https://github.com/freewind/async_demo/blob/master/whilst_until.js

    6. until(test, fn, callback) (与while相似,但判断条件相反)

    var count4 = 0; async.until( function() { return count4>3 }, function(cb) { log('1.4 count: ', count4); count4++; setTimeout(cb, 200); }, function(err) { // 4s have passed log('1.4 err: ',err); // -> undefined } );

    当第一个函数条件为false时,继续执行第二个函数,否则跳出。

    7. queue (可设定worker数量的队列)

    queue相当于一个加强版的parallel,主要是限制了worker数量,不再一次性全部执行。当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。

    该函数有多个点可供回调,如worker用完时、无等候任务时、全部执行完时等。

    定义一个queue,其worker数量为2,并在任务执行时,记录一下日志:

    var q = async.queue(function(task, callback) { log('worker is processing task: ', task.name); task.run(callback); }, 2);

    worker数量将用完时,会调用saturated函数:

    q.saturated = function() { log('all workers to be used'); }

    当最后一个任务交给worker执行时,会调用empty函数

    q.empty = function() { log('no more tasks wating'); }

    当所有任务都执行完时,会调用drain函数

    q.drain = function() { console.log('all tasks have been processed'); }

    放入多个任务,可一次放一个,或一次放多个

    q.push({name:'t1', run: function(cb){ log('t1 is running, waiting tasks: ', q.length()); t.fire('t1', cb, 400); // 400ms后执行 }}, function(err) { log('t1 executed'); });

    q.push([{name:'t3', run: function(cb){ log('t3 is running, waiting tasks: ', q.length()); t.fire('t3', cb, 300); // 300ms后执行 }},{name:'t4', run: function(cb){ log('t4 is running, waiting tasks: ', q.length()); t.fire('t4', cb, 500); // 500ms后执行 }}], function(err) { log('t3/4 executed'); });

    更多详细示例参见:https://github.com/freewind/async_demo/blob/master/queue.js

    8. iterator(tasks) (将几个函数包装为iterator)

    将一组函数包装成为一个iterator,可通过next()得到以下一个函数为起点的新的iterator。该函数通常由async在内部使用,但如果需要时,也可在我们的代码中使用它。

    var iter = async.iterator([ function() { console.log('111') }, function() { console.log('222') }, function() { console.log('333') } ]); console.log(iter()); console.log(iter.next());

    直接调用(),会执行当前函数,并返回一个由下个函数为起点的新的iterator。调用next(),不会执行当前函数,直接返回由下个函数为起点的新iterator。

    对于同一个iterator,多次调用next(),不会影响自己。如果只剩下一个元素,调用next()会返回null。

    更详细示例参见:https://github.com/freewind/async_demo/blob/master/iterator.js

    9. apply(function, arguments..) (给函数预绑定参数)

    apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。

    对于函数:

    function(callback) { t.inc(3, callback); }

    可以用apply改写为:

    async.apply(t.inc, 3);

    还可以给某些函数预设值,得到一个新函数:

    var log = async.apply(console.log, ">"); log('hello'); // > hello

    更详细代码参见:https://github.com/freewind/async_demo/blob/master/apply.js

    10. nextTick(callback) (在nodejs与浏览器两边行为一致)

    nextTick的作用与nodejs的nextTick一样,都是把某个函数调用放在队列的尾部。但在浏览器端,只能使用setTimeout(callback,0),但这个方法有时候会让其它高优先级的任务插到前面去。

    所以提供了这个nextTick,让同样的代码在服务器端和浏览器端表现一致。

    var calls = []; async.nextTick(function() { calls.push('two'); }); calls.push('one'); async.nextTick(function() { console.log(calls); // -> [ 'one', 'two' ] });

    更详细代码参见:https://github.com/freewind/async_demo/blob/master/nextTick.js

     

    二:工具类

    Async中提供了几个工具类,给我们提供一些小便利:

    1. memoize
    2. unmemoize
    3. log
    4. dir
    5. noConflict

    1. memoize(fn, [hasher])

    有一些方法比较耗时,且对于相同的输入总是有相同的输出。这时可以使用memoize给它加个缓存,对于相同的参数只计算一次,以后就直接从缓存中取结果用了。

    比如这里有一个很慢的函数:

    var slow_fn = function(x, y, callback) { 

        console.log(‘start working for: ‘ + x+’,'+y); 

        t.wait(100); 

        console.log(‘finished: ‘ + x+’,'+y); 

        callback(null, ‘im slow for: ‘+x+’,'+y); 

    };

    可以用memoize生成一个新的带缓存的函数:

    var fn = async.memoize(slow_fn);

    试试同样参数调用两次:

    fn(‘a’,'b’, function(err, result) { 

        console.log(result); 

    });

    // 直接得到之前计算好的值 

    fn(‘a’,'b’, function(err, result) { 

        console.log(result); 

    });

     

    注意memoize的参数中还有一个hasher,它是做什么用的呢?它可以让我们自定义如果根据参数来判断是否从缓存中取。默认情况下,两次调用,只有参数完全一样的时候才会从缓存中取。这里我们使用hasher来改变规则。

    var fn_hasher = async.memoize(slow_fn, function(x,y) { 

        return x+y; 

    });

     

    新定义的这个,将根据两个参数的和来判断。

    fn_hasher(‘cd’,'e’, function(err, result) { 

        console.log(result); 

    });

    fn_hasher(‘c’,'de’, function(err, result) { 

        console.log(result); // 可以取得前面(‘cd’,'e’)的计算结果 

                             // im show for: cd,e 

    });

     

    第二次的调用,虽然参数跟第一次不一样,但是其和却一样,所以直接从缓存中拿到前次运行结果。

    2. unmemoize(fn)

    unmemoize的作用正好跟memoize相反,它可以把一个带缓存的函数再变回原样:

    var fn2 = async.unmemoize(fn); 

    console.log(‘unmemoized’);

    fn2(‘a’,'b’, function(err,result) { 

        console.log(result); 

    });

     

    经过unmemoize后,再运行该函数就得重新运算了。

    3. log(function, arguments)

    log用于快速执行某异步函数,并记录它的返回值。试验函数时很方便,不用写那些固定模式的代码。

    var x = function() { 

        this.name = ‘Freewind’; 

    var hello = function(name, callback) { 

        setTimeout(function() { 

            callback(null, ‘hello ‘ + name, ‘nice to see you ‘ + name, x, {a:’123′}); 

        }, 200); 

    };

    async.log(hello, ‘world’);

    打印结果如下:

    hello world 

    nice to see you world 

    [Function] 

    { a: ’123′ }

    可以看到,它直接运行了该函数,并以每行一个参数的形式打印出了结果。

    4. dir(function, arguments)

    该函数与log非常像,不同之处在于,它最终调用了console.dir,而log最终调用了console.log。

    看看使用dir打印的效果如何:

    async.dir(hello, ‘world’);

    结果:

    ‘hello world’ 

    ‘nice to see you world’ 

    [Function] 

    { a: ’123′ }

    仅仅是多了几个单引号。为了弄清楚dir存在的意义(什么情况下应该使用dir而不是log),我提了一个问题,参看:http://stackoverflow.com/questions/10636866/whats-the-difference-between-async-log-and-async-dir

    5. noConflict

    最后是这个noConflict,它仅仅用于浏览器端,在nodejs中没用,这里无法演示。

    它的作用是:如果之前已经在全局域中定义了async变量,当导入本async.js时,会先把之前的async变量保存起来,然后覆盖它。用完之后,调用noConflict()方法,就会归还该值。同时返回async本身供换名使用。

    这里可以看一下它的实现代码:

    // global on the server, window in the browser 

    var root = this, 

        previous_async = root.async;

    if (typeof module !== ‘undefined’ && module.exports) { 

        module.exports = async; 

    else { 

        root.async = async; 

    }

    async.noConflict = function () { 

        root.async = previous_async; 

        return async; 

    };

     

    可以看到,当处于nodejs或者commonjs环境中,它会执行module.exports=async,在其它情况下(通常为浏览器端)才会root.async=async,将async赋值给root。

    在浏览器中的用法如下:

    <script type="text/JavaScript" src="other_lib.js"></script> 

    <script type="text/javascript" src="async.js"></script> 

    <script type="text/javascript">

      // code using async 

      async.noConflict(); 

      // Code that uses other library’s ‘async’ can follow here. 

    </script>

    三:集合操作

    Async提供了很多针对集合的函数,可以简化我们对集合进行异步操作时的步骤。如下:

    1. forEach:对集合中每个元素进行异步操作
    2. map:对集合中的每个元素通过异步操作得到另一个值,得到新的集合
    3. filter:对集合中元素使用异步操作进行筛选,得到符合条件的集合
    4. reject:与filter相似,只是判断条件时正好相反,得到剩下的元素的集合
    5. reduce:使用一个初始值同集合中每一个元素进行异步操作,最后得到一个唯一的结果
    6. detect:得到集合中满足条件的第一个数据
    7. sortBy:对集合中的数据进行异步操作,再根据值从小到大排序
    8. some/any:集合中是否有至少一个元素满足条件
    9. every/all:集合中是否每个元素都满足条件
    10. concat:对集合中的元素进行异步操作,将结果集合并成一个数组

    下面一一解释:

    1. forEach(arr, iterator(item, callback), callback(err))

    如果想对同一个集合中的所有元素都执行同一个异步操作,可以利用forEach函数。注意该函数将重点放在“执行过程”上,忽略运行后产生的数据。如果需要结果,可使用map函数。

    根据执行的方式不同,forEach提供了三个版本:

    1. 集合中所有元素并行执行
    2. 一个一个顺序执行
    3. 分批执行,同一批内并行,批与批之间按顺序

    首先看并行执行的例子,它比较简单,只是打印出传入的元素内容:

    var arr = [{name:'Jack', delay: 200}, 

               {name:'Mike', delay: 100}, 

               {name:'Freewind', delay: 300}];

     

    async.forEach(arr, function(item, callback) { 

        log(’1.1 enter: ‘ + item.name); 

        setTimeout(function(){ 

            log(’1.1 handle: ‘ + item.name); 

            callback(); 

        }, item.delay); 

    }, function(err) { 

        log(’1.1 err: ‘ + err); 

    });

     

    它将打出如下结果:

    42.244> 1.1 enter: Jack 

    42.245> 1.1 enter: Mike 

    42.245> 1.1 enter: Freewind 

    42.350> 1.1 handle: Mike 

    42.445> 1.1 handle: Jack 

    42.554> 1.1 handle: Freewind 

    42.554> 1.1 err: undefined

    最前面的数据是当前的时间值(秒.毫秒),从中可以看到各异步操作是并行执行的。

    如果想同步执行,需要使用forEachSeries函数,它与forEach的用法一模一样,只是执行时是一个一个来的。这里就不给例子了。

    当集合中元素很多,既不想一次全部并行操作,又不想一个一个按顺序来,可以使用forEachLimit函数。它可以设定一批处理几个,每一批内并行执行,批与批之间顺序执行。

    async.forEachLimit(arr, 2, function(item, callback) { 

        log(’1.5 enter: ‘ + item.name); 

        setTimeout(function(){ 

            log(’1.5 handle: ‘ + item.name); 

            callback(null, item.name); 

        }, item.delay); 

    }, function(err) { 

        log(’1.5 err: ‘ + err); 

    });

     

    打印结果如下:

    42.247> 1.5 enter: Jack 

    42.248> 1.5 enter: Mike 

    42.351> 1.5 handle: Mike 

    42.352> 1.5 enter: Freewind 

    42.461> 1.5 handle: Jack 

    42.664> 1.5 handle: Freewind 

    42.664> 1.5 err: undefined

    可以看到前两个是同时开始的,而第三个是等前两个都完成以后才开始的。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/forEach.js

    2. map(arr, iterator(item, callback), callback(err, results))

    map的重点是转换,即把集合中的元素通过异步操作转为另一个对象,最后可以得到转换后的对象数组。它也提供了并行与顺序执行两种方式。

    这里给一个示例,给集合中的每个元素以异步方式增加!!!:

    var arr = [{name:'Jack', delay:200}, {name:'Mike', delay: 100}, {name:'Freewind', delay:300}, {name:'Test', delay: 50}];

    async.map(arr, function(item, callback) { 

        log(’1.1 enter: ‘ + item.name); 

        setTimeout(function() { 

            log(’1.1 handle: ‘ + item.name); 

            callback(null, item.name+’!!!’); 

        }, item.delay); 

    }, function(err,results) { 

        log(’1.1 err: ‘, err); 

        log(’1.1 results: ‘, results); 

    });

     

    打印结果如下:

    54.569> 1.1 enter: Jack 

    54.569> 1.1 enter: Mike 

    54.569> 1.1 enter: Freewind 

    54.569> 1.1 enter: Test 

    54.629> 1.1 handle: Test 

    54.679> 1.1 handle: Mike 

    54.789> 1.1 handle: Jack 

    54.879> 1.1 handle: Freewind 

    54.879> 1.1 err: 

    54.879> 1.1 results: [ 'Jack!!!', 'Mike!!!', 'Freewind!!!', 'Test!!!' ]

    可以看到,对各元素的操作是并行的,结果会汇总在一起交给最后的回调。

    如果想顺序执行,可使用mapSeries,它与map的用法一模一样。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/map.js

    3. filter(arr, iterator(item, callback(test)), callback(results))

    使用异步操作对集合中的元素进行筛选。需要注意的是,iterator的callback只有一个参数,只能接收true或false。

    对于出错,该函数没有做出任何处理,直接由nodejs抛出。所以需要注意对Error的处理。

    提供了并行与顺序执行两种方式。

    并行示例,找到所有>=3的元素:

    async.filter([1,2,3,4,5], function(item, callback) { 

        log(’1.1 enter: ‘ + item); 

        setTimeout(function() { 

            log(’1.1 test: ‘ + item); 

            callback(item>=3); 

        }, 200); 

    }, function(results) { 

        log(’1.1 results: ‘, results); 

    });

     

    打印结果如下:

    16.739> 1.1 enter: 1 

    16.749> 1.1 enter: 2 

    16.749> 1.1 enter: 3 

    16.749> 1.1 enter: 4 

    16.749> 1.1 enter: 5 

    16.749> 1.3 enter: 1 

    16.949> 1.1 test: 1 

    16.949> 1.1 test: 2 

    16.949> 1.1 test: 3 

    16.949> 1.1 test: 4 

    16.949> 1.1 test: 5 

    16.949> 1.1 results: [ 3, 4, 5 ]

    可见找到了满足条件的所有元素。

    如果需要顺序执行,可以使用filterSeries函数,它的用法与filter一样。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/filter_reject.js

    4. reject(arr, iterator(item, callback(test)), callback(results))

    reject与filter相似,只是行为正好相反。当条件为true时,它将丢弃相应的元素。它也提供了并行与顺序执行两种方式。

    并行示例,去掉所有>=3的元素:

    async.reject([1,2,3,4,5], function(item, callback) { 

        log(’1.4 enter: ‘ + item); 

        setTimeout(function() { 

            log(’1.4 test: ‘ + item); 

            callback(item>=3); 

        }, 200); 

    }, function(results) { 

        log(’1.4 results: ‘, results); 

    });

    打印结果如下:

    31.359> 1.4 enter: 1 

    31.359> 1.4 enter: 2 

    31.359> 1.4 enter: 3 

    31.359> 1.4 enter: 4 

    31.359> 1.4 enter: 5 

    31.559> 1.4 test: 1 

    31.559> 1.4 test: 2 

    31.559> 1.4 test: 3 

    31.559> 1.4 test: 4 

    31.559> 1.4 test: 5 

    31.569> 1.4 results: [ 1, 2 ]

    如果想顺序执行,可使用rejectSeries,它与reject用法一样。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/filter_reject.js

    5. reduce(arr, memo, iterator(memo,item,callback), callback(err,result))

    Reduce可以让我们给定一个初始值,用它与集合中的每一个元素做运算,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight。

    这里给个例子,计算出100与某个集合中所有数之和:

    var arr = [1,3,5];

    async.reduce(arr, 100, function(memo, item, callback) { 

        log(’1.1 enter: ‘ + memo +’, ‘ + item); 

        setTimeout(function() { 

            callback(null, memo+item); 

        }, 100); 

    },function(err, result) { 

        log(’1.1 err: ‘, err); 

        log(’1.1 result: ‘, result); 

    });

     

    将打印出结果:

    28.789> 1.1 enter: 100, 1 

    28.889> 1.1 enter: 101, 3 

    28.999> 1.1 enter: 104, 5 

    29.109> 1.1 err: 

    29.109> 1.1 result: 109

    需要注意的是,async中的reduce,不是并行操作,而是对元素一个个顺序操作,所以当元素比较多时,性能会比较弱。如果想提高性能,可使用async.map函数,先并行得到集合中每个元素被处理之后的值,然后再使用Array.prototype.reduce函数处理,性能会快很多。

    对于这个例子:

    async.reduce(arr, 100, function(memo,item,callback) { 

        log(’1.4 enter: ‘+memo+’,'+item); 

        t.inc(item, function(err,n) { 

            log(’1.4 handle: ‘,n); 

            callback(null, memo+n); 

        }); 

    }, function(err,result) { 

        log(’1.4 err: ‘, err); 

        log(’1.4 result: ‘, result); 

    });

     

    它总耗时为0.62秒。如果换成map+array.reduce:

    async.map(arr, function(item, callback) { 

        log(’1.5 enter: ‘, item); 

        t.inc(item, function(err,n){ 

            log(’1.5 handle: ‘, n); 

            callback(null,n); 

        });  

    },function(err, results) { 

        log(’1.5 err: ‘, err); 

        log(’1.5 results: ‘, results); 

        var sum = results.reduce(function(memo, item) { 

            return memo + item; 

        }, 100); 

        log(’1.5 sum: ‘, sum); 

    });

     

    耗时为0.21秒。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/reduce.js

    6. detect(array, iterator(item,callback(test)), callback(result)

    用于取得集合中满足条件的第一个元素。它分为并行与顺序执行两种方式,分别对应函数detect和detectSeries。

    并行示例,找到一个奇数:

    var arr = [{value:1,delay:500}, 

               {value:2,delay:200}, 

               {value:3,delay:300}]; 

    async.detect(arr, function(item,callback){ 

        log(’1.1 enter: ‘, item.value); 

        setTimeout(function() {

            log(’1.1 handle: ‘, item.value); 

            callback(n%2===1); 

        }, item.delay); 

    }, function(result) { 

        log(’1.1 result: ‘, result); 

    });

     

    结果如下:

    09.928> 1.1 enter: 1 

    09.928> 1.1 enter: 2 

    09.928> 1.1 enter: 3 

    10.138> 1.1 handle: 2 

    10.228> 1.1 handle: 3 

    10.228> 1.1 result: { value: 3, delay: 300 } 

    10.438> 1.1 handle: 1 

    10.438> 1.1 handle: 1

    可见得到了最先执行完的那个奇数3.

    更多详细示例:https://github.com/freewind/async_demo/blob/master/detect.js

    7. sortBy(array, iterator(item,callback(err,result)), callback(err,results))

    对集合内的元素进行排序,依据每个元素进行某异步操作后产生的值,从小到大排序。

    示例:

    var arr = [3,6,1];

    async.sortBy(arr, function(item, callback) { 

        setTimeout(function() { 

            callback(null,item); 

        }, 200); 

    }, function(err,results) { 

        log(’1.1 err: ‘, err); 

        log(’1.1 results: ‘, results); 

    });

     

    打印结果如下:

    26.562> 1.1 err: null 

    26.562> 1.1 results: [ 1, 3, 6 ]

    可以看到集合中的数据从小到大排好了序。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/sortBy.js

    8. some/any(arr, iterator(item,callback(test)), callback(result))

    当集合中是否有至少一个元素满足条件时,最终callback得到的值为true,否则为false。它有一个别名叫any。

    判断集合中是否有元素小于等于3:

    async.some([1,2,3,6], function(item,callback){ 

        log(’1.1 enter: ‘,item); 

        setTimeout(function(){ 

            log(’1.1 handle: ‘,item); 

            callback(item<=3); 

        },100);    

    }, function(result) { 

        log(’1.1 result: ‘, result); 

    });

    打印结果如下:

    36.165> 1.1 enter: 1 

    36.165> 1.1 enter: 2 

    36.165> 1.1 enter: 3 

    36.165> 1.1 enter: 6 

    36.275> 1.1 handle: 1 

    36.275> 1.1 result: true 

    36.275> 1.1 handle: 2 

    36.275> 1.1 handle: 3 

    36.275> 1.1 handle: 6

     

    可见的确得到了结果true。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/some.js

    9. every/all(arr, iterator(item,callback), callback(result))

    如果集合里每一个元素都满足条件,则传给最终回调的result为true,否则为false

    在下面的示例中,因为集合中每个元素都<=10,所以最终结果为true

    async.every(arr, function(item,callback){ 

        log(’1.1 enter: ‘,item); 

        setTimeout(function(){ 

            log(’1.1 handle: ‘,item); 

            callback(item<=10); 

        },100);    

    }, function(result) { 

        log(’1.1 result: ‘, result); 

    });

     

    打印如下:

    32.113> 1.1 enter: 1 

    32.123> 1.1 enter: 2 

    32.123> 1.1 enter: 3 

    32.123> 1.1 enter: 6 

    32.233> 1.1 handle: 1 

    32.233> 1.1 handle: 2 

    32.233> 1.1 handle: 3 

    32.233> 1.1 handle: 6 

    32.233> 1.1 result: true

    可见最终结果为true

    更多详细示例:https://github.com/freewind/async_demo/blob/master/every.js

    10. concat(arr, iterator(item,callback(err,result)), callback(err,result))

    将合并多个异步操作的结果合并为一个数组。

    在下面的示例中,将集合中的每一个元素都加倍:

    async.concat(['aa','bb'], function(item,callback) {

        setTimeout(function() {

            callback(null, [item, item]);

        }, 100);

    }, function(err, values) {

        log(’1.1 err: ‘, err);

        log(’1.1 values: ‘, values);

    });

    打印如下:

    13.539> 1.1 err:

    13.639> 1.1 values: [ 'aa', 'aa', 'bb', 'bb' ]

    打印出来的是经过合并后的数组。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/concat.js

    展开全文
  • async 异步编程

    2020-11-16 16:03:27
    本系列课程带大家学习asyncio异步编程,深入浅出并结合大量案例来进行讲解。课程从前到后分别讲解:协程、实现协程、协程的意义...async关键字、task对象、future对象、FastAPI框架异步案例、MySQL异步、Redis异步等。
  • async function

    千次阅读 2019-11-13 10:05:50
    async function 声明定义了一个异步函数,它返回一个AsyncFunction对象。异步函数 是指通过 事件循环(event loop) 异步执行的函数,通过返回一个隐式的 Promise 作为其结果。使用异步函数的代码的语法和结构更像...
  • 异步 async 模块如何工作的示例
  • async-global-executor-在async-executor和async-io之上构建的全局执行器async-global-executor在async-executor和async-io之上构建的全局执行器功能async-io:如果启用,则async-global -executor将在内部使用async...
  • dist.async 基于core.async的分布式通道
  • require ( [ 'async' ] , function ( async ) { } ) ; 承诺和异步/等待 我建议使用 。 它针对Promise处理进行了优化,并且具有与neo-async几乎相同的功能。 Node.js 标准 $ npm install neo-async var async = ...
  • 从适合async.auto()的输入对象中选择所需函数的特定子树(或子树的联合async.auto() 。 目标是使用async.auto简化编写异步工作流,替换否则代码将有条件地改变输入对象或函数将在执行前检查其先决条件的情况。 例子 ...
  • 一个async .await 实现。 例子 通过my-proxy-server.com:54321连接到google.com:80 : use tokio :: net :: TcpStream; use tokio :: io :: BufStream; use async_socks5 :: {connect, Result }; #[tokio::main] ...
  • async函数

    千次阅读 2020-10-28 20:17:05
    async函数 async函数是什么 ECMAScript 2017规范引入了async 函数,该函数的主要目的就是简化使用 Promises, 异步调用的操作,并对一组Promises执行某些操作。正如 Promises 类似于结构化回调,async/await 类似于...
  • TurboPower Async

    2012-09-25 15:36:16
    TurboPower Async属性的说明,中文的。
  • 高清彩版 Async in C# 5.0: Unleash the Power of Async 高清彩版 Async in C# 5.0: Unleash the Power of Async
  • Async Javascript

    2012-12-21 01:24:40
    Clearly depicts the event driven javascript and how async benefits the world.
  • :waving_hand: 欢迎使用render_async 让我们再次加快Rails页面的速度 :horse: render_async可以使您的页面向用户更快地显示。 通过将部分视图呈现给视图,页面可以无缝无缝地变得更快。 局部渲染是异步的,它使...
  • core.async助手 Core.async是处理Clojure和ClojureScript程序中异步功能的标准方法。 尽管core.async是基于构建的,但通常(特别是在CLJS中)希望具有类似于。 Core.async提供了一个promise-chan ,它是一个...
  • async-std的宏。 安装 $ cargo add async-macros 安全 此板条箱将unsafe的销钉投影使用。 贡献 想加入我们吗? 请查看我们的并看一下其中的一些问题: 参考 -在join + try_join宏是旧的直接端口macro_rules从impls...
  • 下面小编就为大家带来一篇细数Ajax请求中的async:false和async:true的差异。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 452,192
精华内容 180,876
关键字:

async