>>分享Web前端开发技术,并对孙卫琴的《精通Vue.js:Web前端开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 26137 个阅读者 刷新本主题
 * 贴子主题:  Javascript中的异步 回复文章 点赞(0)  收藏  
作者:sunshine    发表时间:2019-08-12 22:23:37     消息  查看  搜索  好友  邮件  复制  引用


在C#,Java中,异步方法,通常是伴随多线程,并发等术语一起出现的,比如C#中的async方法,是运行在一个线程池线程上,并且在异步方法运行完成后,有一个回调函数通知主线程。

那么由于Javascript是单线程的,它的异步又是怎么解释的?

首先对异步方法给一个定义,什么样的方法算是异步方法。我认为异步方法最主要有2点,一个是不阻塞当前代码的执行,另一个是有回调方法。即异步方法运行完可以通知主线程。

事实上,当说起Javascript的异步时,不要忽略了,Javascript中其实有2种异步,一种是基于浏览器的的异步IO,比如ajax的本质。另一种是基于计时方法setTimeout和setInterval的异步。

对于异步IO,比如ajax,写代码的时候都是顺序执行的,但是在真正处理请求的时候,有一个单独的浏览器线程来处理,并且在处理完成后会触发回调。这种情况下,参与异步过程的其实有2个线程主体,一个是javascript的主线程,另一个是浏览器线程。

熟悉Javascript的人都知道,Javascript内部有一个事件队列,所有的处理方法都在这个队列中,Javascript主线程就是轮询这个队列处理,这个好处是使得CPU永远是忙碌状态。这个机制和Windows中的消息泵是一样的,都是靠消息(事件)驱动。对于这个消息队列的描述,可以参考http://www.iamued.com/qianduan/1645.html这个文章。

在Javascript中,通过setTimeout函数也可以实现“不阻塞”和“有回调”。比如,下面的代码:
function f1(callback){
  setTimeout(function () {
     // f1的任务代码
    callback();
   }, 1000);
}
f1(f2);

通过这种写法,javascript在调用f1方法的时候,将真正的逻辑放到1秒后,并且在运行完正真的逻辑后,执行了f2方法。仔细的分析一下,其实这种所谓的不阻塞其实只是将阻塞延迟了。单线程环境下,并没法真正的异步。事实上,setTimeout方法对于时间的精度非常差,并不能真的保证是在1秒后执行,如果事件队列中有一个长时间的方法在运行,那么就阻塞了真正的f1方法内容的运行,直到长时间的方法允许完毕。等到轮到f1的真正逻辑开始运行的时候,其他的代码同样的要等到它运行完毕才能运行。

比如下面的代码:

setTimeout(function(){alert('do');},0);
var i=0;
while(i<100000){
console.log(i);
i++;
}

并不会马上运行alert,而是会等到while运行完毕才alert。根据《Javascript异步编程》这本书中提到,setTimeout和setInterval的延时最小间隔是4ms,Quora上也有总结过[url=http://www.quora.com/How-accurate-are-JavaScript-timers]http://www.quora.com/How-accurate-are-JavaScript-timers[/url]。

在Javascript中实现异步的另一个方法是Web Worker,web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。Web Workers依赖于浏览器,目前支持的lSafari, Chrome, Opera, Internet Explorer (version 10) 和Mozilla Firefox.一旦使用Web Workers就等于使用了多线程技术。Web Workers的更多细节,可以参考网上的文档[url=http://www.w3school.com.cn/html5/html_5_webworkers.asp]http://www.w3school.com.cn/html5/html_5_webworkers.asp[/url]。

[url=http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html]http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html[/url]

            

----------------------------
原文链接:https://blog.51cto.com/cnn237111/1556987

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-02-24 12:27:45 重新编辑]
  Java面向对象编程-->第一个Java程序
  JavaWeb开发-->Web运作原理(Ⅱ)
  JSP与Hibernate开发-->数据库事务的并发问题的解决方案
  Java网络编程-->Java网络编程入门
  精通Spring-->Vue CLI脚手架工具
  Vue3开发-->Vue简介
  JavaScript数组去重(12种方法)
  在Typescript脚本中使用axios
  Axios拦截器的用法
  把99%的程序员烤得外焦里嫩的JavaScript面试题
  前端面试题及答案汇总
  前端图片压缩库images-quickly-compress
  一看就懂得移动端rem布局、rem如何换算
  SQL NULL 值
  JavaScript Error(错误) 对象
  HTML支持的多媒体(Media)
  HTML5 播放Audio(音频)
  HTML5 内联 SVG
  HTML 头部的元素的用法
  JavaScript 的HTML DOM 事件
  一文读懂前端技术演进:盘点Web前端20年的技术变迁史
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。