Javascript中的异步
在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上也有总结过http://www.quora.com/How-accurate-are-JavaScript-timers。
在Javascript中实现异步的另一个方法是Web Worker,web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。Web Workers依赖于浏览器,目前支持的lSafari, Chrome, Opera, Internet Explorer (version 10) 和Mozilla Firefox.一旦使用Web Workers就等于使用了多线程技术。Web Workers的更多细节,可以参考网上的文档http://www.w3school.com.cn/html5/html_5_webworkers.asp。
http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html
本文出自 “一只博客” 博客,出处http://cnn237111.blog.51cto.com/2359144/1556987
Javascript中的异步的更多相关文章
- javascript中的异步 macrotask 和 microtask 简介
javascript中的异步 macrotask 和 microtask 简介 什么是macrotask?什么是microtask?在理解什么是macrotask?什么是microtask之前,我们先 ...
- 【JS】336- 拆解 JavaScript 中的异步模式
点击上方"前端自习课"关注,学习起来~ JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS ...
- 【JS】285- 拆解 JavaScript 中的异步模式
JavaScript 中有很多种异步编程的方式.callback.promise.generator.async await 甚至 RxJS.我最初接触不同的异步模式时,曾想当然的觉得 promise ...
- [技术翻译]在现代JavaScript中编写异步任务
本周再来翻译一些技术文章,本次预计翻译三篇文章如下: 04.[译]使用Nuxt生成静态网站(Generate Static Websites with Nuxt) 05.[译]Web网页内容是如何影响 ...
- JavaScript中的异步函数
JavaScript中的异步函数 ES8 的 async/await 旨在解决利用异步结构组织代码的问题.为此, ECMAScript 对函数进行了扩展,为其增加了两个新关键字: async 和 aw ...
- javaScript中的异步编程模式
1.事件模型 let button = document.getElementById("my-btn"); button.onclick = function(event) { ...
- JavaScript中的异步 macrotask 和 microtask
看过很多setTimeout.Promise执行顺序的面试题,一直不明白为啥都是异步操作,Promise就牛×些呢?直到了解了macrotask和micromask才恍然大悟... 先来一道面试题助助 ...
- javascript中的异步编程
正常情况下js都是顺序执行的,但是也有很多场景下实际上是异步操作: 1.定时器都是异步操作 2.事件绑定都是异步操作 3.AJAX中一般我们都采取异步操作(也可以同步) 4.回调函数可以理解为异步(不 ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
随机推荐
- 美团实习Java岗面经,已拿offer
作者:icysnowgx 链接:https://www.nowcoder.com/discuss/71954?type=2&order=3&pos=10&page=1 来源:牛 ...
- 记一个logrotate的配置文件权限问题
问题描述 从git仓库更新了别人配置好的logrotate,发现不能正常运行.手工执行报错 error: Ignoring syslog because of bad file mode - must ...
- Linux系统调用、新增系统调用方法【转】
转自:http://blog.chinaunix.net/uid-25374603-id-3401045.html 说明: 系统调用是内核和应用程序间的接口,应用程序要访问硬件设备和其他操作系统资源, ...
- SSO单点登录的发展由来以及实现原理【转】
单点登录以及权限,在很早之前都有写过,不过都比较简单,今天就具体说一下,以及下一步要做的 1.web单系统应用 早期我们开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的, ...
- 《深入理解Java虚拟机》笔记--第十三章、线程安全与锁优化
先保证并发的正确性,然后在此基础上来实现高效. 线程安全: 当多个线程访问一个对象时,如果不考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操 ...
- DHCP简单配置
DHCP是什么? DHCP动态主机地址管理协议(Dynamic Host Configuration Protocol)是一种基于UDP协议且仅限用于局域网内使用的网络协议,最主要的用途是为局域网内部 ...
- Nginx源码分析--数组(转)
原文地址:http://blog.csdn.net/marcky/article/details/5747431 备注:以下关于Nginx源码的分析基于淘宝开源项目Tengine. Nginx中对数组 ...
- log优化
isLoggable(Level level) 包含计算的日志记录用isLoggable判断下. debug info warn error ,一般记录error, 但是其他里面的计算还是 ...
- flask-login 学习(1)
今天的目标,就是学习 flask-login.争取用1天时间,掌握个大概. 第一步:掌握flask-login的大致使用,具体参考了:https://www.centos.bz/2017/09/fla ...
- 【ios开发之疑难杂症】xcode运行出现SpringBoard 无法启动应用程序(错误:7)
问题:xcode运行出现SpringBoard 无法启动应用程序(错误:7) 解决方案: 重启模拟器