JavaScript深刻浅出异步编程1、setTimeout和setInterval

最近开发了一个适用于iOS上的混合开发库,支持JavaScript的开发,开发完之后对于JavaScript中的一些特性有了更加深刻的了解。也就有了这篇文章,后续还会陆续写一些其余的关于JavaScript的文章。javascript

异步编程通常跟多线程有关,而咱们都知道JavaScript是单线程执行的,那何来异步之说?java

事实上,但凡在JS中执行的代码都是单线程执行的。c++

然而,咱们日常开发JavaScript的时候常常会提到异步编程的概念,并且在实际的开发过程当中也常常会用到异步编程。那先说下咱们是怎么用的,从最简单的setTimeout提及,而后一步一步的说到ES8中的asyncawait编程

setTimeout、setInterval

setTimeout(function(){
    console.log('timeout');
},1000);
复制代码

执行上面的代码1秒后输出timeout。下面换一种方式,使用setInterval来实现。浏览器

var interval = setInterval(function () {
    console.log('timeout');
    clearInterval(interval);
}, 1000);
复制代码

上面两种方式实现的效果是同样的,都是在等待1秒后执行function中的代码。多线程

看到上面的代码,但凡写过其余语言的好比:c++、java、OC等的,都知道这其实就是一个定时器,而setTimeout稍微特殊点,只会执行一次,而setInterval可以执行屡次,直到显示取消为止。异步

举上面的例子主要是说明,在JavaScript中,setTimeoutsetInterval能够实现相似异步的效果。async

不一样的语言对于定时器的实现方式有可能不同,甚至同一种语言,提供多种不一样的定时器API,就拿Objectiv-c来讲,起码有三种方式实现定时器的效果,可是无论什么语言,用什么方式来实现,工做原理差很少,异步编程

就是当定时器获取到某个信号的时候,在建立该定时器的线程中插入任务。这样的过程能够理解为线程调度。由于定时信号不必定在你回调的线程上触发的,该信号有可能直接由硬件中断产生,也有多是软件模拟产生,可是在使用的时候都会在建立的线程得到回调。ui

所以,定时器本质上仍是单线程的,跟异步编程不要紧。我举个例子你就明白了

var t1 = new Date();
setTimeout(function(){
    var t2 = new Date();
    console.log('diff:'+(t2-t1));
},1000);

while (new Date() - t1 < 2000) {
}
复制代码

上面的代码你以为是输出1000呢?仍是2000

实际的代码输出是diff:2000,具体是2000多少要看实际状况。举这样的例子说明什么呢,正是说明setTimeout仍是串行执行的,你能够理解为见缝插针方式。所以setTimeout压根就算不上异步

一个残酷的现实是,javascript中不存在真的异步,一切异步都是假象。

全部的JS代码都是在同一个线程上执行的,所以不存在多线程的概念,也就不存在真正的异步编程

其实某些浏览器支持workerAPI,算是真的多线程。可是本篇不作介绍。

既然本篇的主题是异步编程,那么就算是假象,也得继续了。

XMLHttpRequest

我记得JS的异步编程的概念被提出来是从XMLHttpRequest(Ajax)开始的,而这里的异步指的只是实际的http请求是在非JS线程执行的,而请求完毕后的回调仍是在JS线程执行的。这样看起来是异步的,可是咱们要注意到,http异步请求不是在JS线程上执行的,而是由浏览器负责的,跟JS不要紧。可是,正是由于有了这样的模型,才使得一些本来没法实现的功能变得可能。

相关文章
相关标签/搜索