写js写傻了,明天研究一下异步
在html某元素上绑定一个click事件,该事件是一个执行事件很长的函数,比如执行几十亿或几百亿次加法,那么在这个函数执行的过程中,其他元素绑定的事件,是如何触发的呢,异步触发还是同步,触发时是怎么执行的呢,也是同步执行下来的么?明天好好研究一下。
目前找到一篇不错的博文,今晚看不完了,明天接着研究及该文章其参考的文章 文章2
通过以上文章,已经对js引擎的单线程以及浏览器内核的多线程机制了解了一番,那么对于jquery的延迟对象以及ES6的promise的异步又是怎样实现的呢。目前自己的结论是,promise是通过代码组织方式实现异步的,但仍要服于js单线程以及浏览器多线程的机制。看下面的代码
<body> <div class="app">gagggg</div> <div class="app2" >cccccc</div> <script> var defer = $.Deferred(); defer.done(function(){ alert("OK OK OK"); }) $(function () { $('.app').click(function () { var a = 0; for (var i = 0; i < 5000000000; i++) { a = a + i + 1; } $('.app').addClass('red'); console.log('app1'); }); $('.app2').click(function () { defer.resolve(); }); }) </script> </body>
.app绑定的事件在我本机上大概要6秒左右的样子执行完,在.app刚被触发的时候,立马点击.app2,发现defer.done并没有执行,也就是说defer.resolve没有触发,因为resolve在click事件内部,而事件是浏览器的事件引擎来处理的,事件发生时,事件引擎将事件处理函数放到js引擎队列的最后 ,所以resolve仍要等待js队列执行到这儿才能触发。
那jquery的延迟对象究竟是什么东西呢。上面已经说了自己目前的结论,是代码的一直组织方式。类似与回调函数,defer.resolve()可以看成是一函数的执行,该函数执行到最后,会调用defer.done(function(){ })里的匿名函数,更精确的讲,是回调机制的另一种组织方式。自己写个大概的deferred的实现流程吧,不是很准确。
var defer = $.Deferred(); var fun1 = function () {}; defer.done(fun1); defer.resolve();
resolve将done里的函数放在了自己的执行队列里,不过resolve自身的被调用仍受制于js单线程以及浏览器多线程的机制。
写到这儿,好想去jquery源码去研究一下延迟对象是怎样写出来的。先等等,等我能熟练用webpack+bable+es6+vue全家桶+sass+compass构建出一个vue2.0工程。