nodejs异步非阻塞IO及实例(cs)
2013-10-29 16:32
531 查看
[node-sync is a simple library that allows you to call any asynchronous function in synchronous way.]
nodejs的最大特点,事件驱动,异步非阻塞,有且只有一个线程。
(1)异步的初步理解
nodejs包含大量异步过程和回调函数(callback),下面的代码实现了ls的功能。
可以看到,上面代码先调用了同步的readdir函数读取当前路径下的filename。nodejs官方文档中,fs一节有很多file的同步实现函数及对应非同步函数,链接:http://nodejs.org/api/fs.html 。异步情况下,应用程序会进行下一个函数,而不会等待回调函数结束,这就是所谓的异步非阻塞。
PS:如果我们需要使用异步函数的结果,必须在回调函数中调用
(2) 顺序执行逻辑不同的异步函数
这种情况较为多见,一般分为两种情况:
第一个异步函数的结果是第二个(异步)函数的参数
这种情况比较简单,只需要层层回调就可以了,大体框架如下:
# 定义异步函数fun1fun1 = (_parms, _cb)-> ...
... # 调用fun1,后面定义回调函数对fun1的数据进行处理 fun1 _parms, (_data)-> ...
第一个异步函数的处理结束后才能调用第二个(异步)函数
这种情况下,也是层层回调,但是回调函数本身只是调用下一个异步函数,目的只是为了保证顺序执行。比如需要处理文件,先读取下日志并保存,然后排序合并。然后删除原始日志,排序合并必须在日志都读取保存完成后,而删除必须在合并完成后,这就是一种必须的顺序执行,否则数据就会不准确。大体框架如下:
# 定义三个函数fun*
fun1 = (_parms1, _cb)-> ...
fun2 = (_parm2, _cb)-> ...
fun3 = (_parm3)-> ...
...# 调用处理,定义了两个函数直接调用下一步的函数,并用作回调函数_funcb2 = -> fun3 _parms3_fun1cb = -> fun2 _parms2, _funcb2fun1 _parms1, _fun1cb
上面的cb函数必须在fun1前定义,但执行是从fun1开始的,它执行完成再调用_fun1cb,它又会执行fun2函数,完成后调用_funcb2,这样就满足了上面顺序执行的需求。
(3)顺序执行逻辑相同异步函数
执行逻辑相同的异步函数时,上面(2)中的层层调用的方法并不优雅,但同一般写法不同,这时nodejs使用while,break语句会报错。此时,可以使用函数嵌套函数的方法。例子如下:
getdata是通过url获取页面数据的方法,当我们有一组urls时,可以调用request方法来获取数据。
request方法中,获取的data存在_ret中,并作为参数传递给再次调用的request函数直到urls遍历完成。
参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html
nodejs的最大特点,事件驱动,异步非阻塞,有且只有一个线程。
(1)异步的初步理解
nodejs包含大量异步过程和回调函数(callback),下面的代码实现了ls的功能。
# functions like ls command # result <filenames of ./> <end> <filenames of ./> fs = require 'fs' filenames = fs.readdirSync '.' for filename in filenames console.log filename fs.readdir '.', (_err, filenames)-> for filename in filenames console.log filename console.log 'end'
可以看到,上面代码先调用了同步的readdir函数读取当前路径下的filename。nodejs官方文档中,fs一节有很多file的同步实现函数及对应非同步函数,链接:http://nodejs.org/api/fs.html 。异步情况下,应用程序会进行下一个函数,而不会等待回调函数结束,这就是所谓的异步非阻塞。
PS:如果我们需要使用异步函数的结果,必须在回调函数中调用
(2) 顺序执行逻辑不同的异步函数
这种情况较为多见,一般分为两种情况:
第一个异步函数的结果是第二个(异步)函数的参数
这种情况比较简单,只需要层层回调就可以了,大体框架如下:
# 定义异步函数fun1fun1 = (_parms, _cb)-> ...
... # 调用fun1,后面定义回调函数对fun1的数据进行处理 fun1 _parms, (_data)-> ...
第一个异步函数的处理结束后才能调用第二个(异步)函数
这种情况下,也是层层回调,但是回调函数本身只是调用下一个异步函数,目的只是为了保证顺序执行。比如需要处理文件,先读取下日志并保存,然后排序合并。然后删除原始日志,排序合并必须在日志都读取保存完成后,而删除必须在合并完成后,这就是一种必须的顺序执行,否则数据就会不准确。大体框架如下:
# 定义三个函数fun*
fun1 = (_parms1, _cb)-> ...
fun2 = (_parm2, _cb)-> ...
fun3 = (_parm3)-> ...
...# 调用处理,定义了两个函数直接调用下一步的函数,并用作回调函数_funcb2 = -> fun3 _parms3_fun1cb = -> fun2 _parms2, _funcb2fun1 _parms1, _fun1cb
上面的cb函数必须在fun1前定义,但执行是从fun1开始的,它执行完成再调用_fun1cb,它又会执行fun2函数,完成后调用_funcb2,这样就满足了上面顺序执行的需求。
(3)顺序执行逻辑相同异步函数
执行逻辑相同的异步函数时,上面(2)中的层层调用的方法并不优雅,但同一般写法不同,这时nodejs使用while,break语句会报错。此时,可以使用函数嵌套函数的方法。例子如下:
# Don't try to do this with 'while' and 'break' # This's a example of asynchronous function nested asynchronous function http = require "http" # 获取某url的数据 getdata = (_url, _callback) -> http.get _url, (_res)-> _body = "" _res.on 'data', (_chunk) -> _body += _chunk _res.on 'end', -> try _stat = JSON.parse _body catch _e process.stderr.write _e process.exit 1 if not _callback console.log _stat else _callback _stat " " # 获得多个url的数据 request = (_urls, _ret, _callback = null)-> _url = _urls.shift() getdata _url[1], (_data)-> _ret[_url[0]] = _data _callback = console.log if not _callback return _callback _ret if _urls.length is 0 request _urls, _ret, _callback module.exports = {getdata, request}
getdata是通过url获取页面数据的方法,当我们有一组urls时,可以调用request方法来获取数据。
request方法中,获取的data存在_ret中,并作为参数传递给再次调用的request函数直到urls遍历完成。
参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html
相关文章推荐
- IO复用模型同步,异步,阻塞,非阻塞及实例详解
- nodejs的异步非阻塞IO
- IO模型同步与异步阻塞与非阻塞的区别
- 转:IO模型-- 同步和阻塞,异步和非阻塞的区别
- 转:IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇) .
- 深入了解几种IO模型(阻塞非阻塞,同步异步)
- NodeJS 使用Socket.IO实例
- IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
- IO模式——同步(阻塞、非阻塞)、异步
- IO中同步、异步与阻塞、非阻塞的区别
- IO - 同步,异步,阻塞,非阻塞
- IO中同步、异步与阻塞、非阻塞的区别 2013-05-31 11:51:19
- IO中同步、异步与阻塞、非阻塞的区别
- IO模型:同步、异步、阻塞、非阻塞
- IO的学习笔记 - 同步,异步,阻塞,非阻塞
- Socket通信之BIO(同步阻塞IO)、PAIO(伪异步阻塞IO)、NIO(异步非阻塞IO)、AIO(异步非阻塞IO)、netty5之IO
- Linux Driver互斥、异步通知、阻塞与非阻塞综合实例
- 网络IO之阻塞、非阻塞、同步、异步总结
- IO - 同步,异步,阻塞,非阻塞
- 网络IO之阻塞、非阻塞、同步、异步总结