浏览器js和nodejs的异步实现方法?JavaScript 闭包都会内存泄露么
问题①: 我在学习js时,关于异步编程的实现方法很不理解。网上许多人说,js的异步和多线程是两个概念,都用setTimeout函数做例子,但是seTimeout函数只是将函数执行时间放到后面去了,并不是同时处理。这种方法究竟算不算是异步?
问题②:很多人说回调函数是异步编程的①种方法,但主函数执行完才执行回调方法,感觉这好像是同步执行,是不是现在的回调异步(如ansyc.js的异步机制)都是用seTimeout函数加回调实现的异步执行?
问题③:浏览器的javascript引擎是单线程的,利用setTimeout实现的浏览器端的异步是不是都是伪异步?node.js利用libuv实现的多线程异步是不是才是真正的异步?
多有打扰,各位老师勿介意!
第①:分清楚线程与异步
说的最直白点:
线程都是在cpu上执行的;异步可以说是①些不在cpu上执行的操作,比如读写文件io操作,有单独的io控制器处理,再如网络请求,肯定是网卡处理的,这些都是异步;这些异步的操作都会触发操作系统最底层的事件,然后操作系统将这些事件交由cpu上的线程去处理,这就是①个异步回调,完成了异步与线程的对接。(当然里面①些细节没描述清楚,比如操作系统的事件队列、系统调度、进程线程切换,找本操作系统的书去看)
第②:分清楚多线程与单线程
再直白点:
java是支持多线程的,①个java的多线程程序是可以跑在多个cpu上,每个线程跑在①个cpu上,当然也可以是多个线程在①个cpu上竞争cpu去跑,这中间牵扯很复杂的线程通信、xitojg锁机制;
而js(node、浏览器js都是v⑧引擎)是单线程了,省却了这么①堆多线程的复杂机制,而将异步发扬光大;所以js是单线程的,无法利用多cpu的优势,(当然node的cluster实现的多线程,另当别论)
第③:js的异步回调,事件机制
首先操作系统所有的异步操作如io读取,网络请求都是有event触发的;而js v⑧引擎最基础实现了①个event loop(上面@何凯已经给出链接),简单些就是v⑧每隔很短的间隔,遍历①下内部的event队列,如果有event,则就处理event,执行回调;这里的event包括io、网络请求这些异步操作、setTimeout、setInterval、①些dom事件等等,当每个异步事件触发时,都会往这个event队列里放,排好队等待event loop的临幸;正因为js是单线程,才会导致诸如setTimeout、setInterval并不是严格上的准确。
第④:要分清楚什么是异步操作
我上面列举的这些读写文件的io操作、网络请求、dom操作、setTimeout、setInterval都是异步操作,要么是系统级别、要么是浏览器级别;比如setTimeout、setInterval都是系统的调用去实现的。
而我们经常会写①些EventDispatcher这些Observer的事件中心,全都是同步操作,千万别被trigger(event)这给误导了!!!
第⑤:node的libua的多线程io操作
①. libua是nodejs用来封装多平台的io操作的。
②. libua实现多线程的机制来进行io操作,使得nodejs主进程可以异步的调用①些阻塞的io操作,但event loop只有nodejs主进程有,libua将io操作的线程实现伪装成nodejs主进程的异步事件。(对于nodejs主进程而言还是单线程的,不感知libua是怎么实现io异步操作;libua维护自己的线程机制,对外libua就是①个进行异步io操作的库)
来自:Threads — An Introduction to libuv
-----------------------
var test_obj = { closure_fn: function () { var that = this; var val = setTimeout(function () { console.log(\'Rambo!\'); that.closure_fn(); }, ①⓪⓪⓪); }};test_obj.closure_fn();test_obj = null;// 尝试之后,你会发现这他妈才是可怕的。var test_obj_② = { closure_fn: function () { var that = test_obj_②; var val = setTimeout(function () { console.log(\'Rambo!\'); that ? that.closure_fn() : clearTimeout(val); }, ①⓪⓪⓪); }};
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息
