2011-09-22 39 views

回答

8

像这样的异步迭代函数对于每个项目执行的操作取决于底层的异步任务很有用。

例如,在Node.js中,文件系统操作是异步的(它们发生在单独的非JavaScript线程中,并在完成时调用回调函数)。例如,如果您想要将文件名列表映射到这些文件的信息上,那么在文件系统操作回调之前,您将无法返回映射结果。同样,JavaScript数据库驱动程序往往是异步的(他们在另一个线程中工作,并在完成时调用JavaScript函数)。

例如,假设您有一个用户ID列表(例如堆栈溢出问题中涉及的用户列表),并且您想将它们映射到每个用户的详细信息。随着async.js,这可能是这样的:

async.map([2389, 6344, 27], 
    function(id, callback){ 
     database.users.find({ id: id }, function(error, user){ 
      if (error) { 
       callback(error); 
      } else { 
       callback(null, { 
        name: user.name, 
        reputation: user.reputation, 
        picture: user.picture 
       }); 
      } 
     }) 
    }, 
    function(error, results){ 
     /* results contains: 
      [ 
       { name: "Bob", reputation: 10, picture: "http://…" }, 
       { name: "Fred", reputation: 2910, picture: "http://…" }, 
       { name: "Steve", reputation: 25000, picture: "http://…" } 
      ] 
     */ 
    } 
); 

的迭代函数将被调用数组中的每个项目,将启动一个数据库查询来获取有关该用户的详细信息。在开始下一个查询之前,它不会等待每个查询完成。数据库查询可能会很快完成,或者可能需要一些时间。如果它们是同步的,那么它们一次只能运行一个。更糟糕的是,在数据库查询运行时,JavaScript线程将无法执行其他任何操作。

这样,无论数据库查询需要多长时间。当他们离开时,JavaScript线程可能处于空闲状态,或者它可能不能处理其他事情(如对服务器的另一个请求)。

当每个数据库请求完成(他们甚至可能不会完成在它们启动的顺序相同!),它所谓的回调函数,这使有关用户的信息到一个对象并把它给回调。 async.js保持跟踪到目前为止已经返回的迭代,并且只在每个迭代完成后调用最终回调。

您可以在async.js文档中找到类似的示例。

在浏览器中,异步操作较少,但您可以使用async.js来请求服务器,加载一组资源(如脚本或图像)并确保它们全部加载成功或在窗口之间发送消息。

+0

例子请...其他然后添加嵌套的回调Asyn函数没有明显的好处 – Linsey

+0

@林赛:你打败了我!我从我的手机上发布了这个问题,并且想在我回到我的电脑后添加一个例子。 – s4y

+0

感谢这个例子,我会惹恼它并回到后者。 – Linsey