asyn vs sync forEach,map,filter

时间:2011-09-22 01:12:46

标签: javascript asynchronous

查看Asyncunderscore.js的异步分支,它会显示同步forEachmapfilter的asyn版本。

考虑到Javascript是单线程的,返回一个有序,映射,forEached ...数组的值是什么值将返回的值传递给回调函数?

1 个答案:

答案 0 :(得分:8)

当您对每个项目执行的操作依赖于底层异步任务时,这样的异步迭代函数非常有用。

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

例如,假设您有一个用户ID列表(如Stack Overflow问题中涉及的用户列表),并且您希望将它们映射到有关每个用户的详细信息。使用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线程可能处于空闲状态,或者可能没有处理其他事情(比如对服务器的另一个请求)。

当每个数据库请求完成时(并且它们甚至可能没有按照它们的启动顺序完成!),它会调用其回调函数,该函数将有关用户的信息放入对象并将其交给其< / em>回调。 async.js跟踪到目前为止返回的迭代次数,并且只在每次迭代完成后调用最终回调。

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

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