众所周知,JS是单线程运行机制,但是当我们在使用AJAX请求时会有async选项,来实现异步。
那么小编今天来简单的说一下关于JS的异步到底是怎么实现的。
我们先测试这样一段代码:
self.setInterval("funA()", 1000);
self.setInterval("funB()", 1000);
function funA() {
console.log('A');
}
function funB() {
console.log('B');
}
输出结果很好,A在执行同时B也在执行。
我们再来测试这样一段代码:
self.setTimeout("funA()", 8000);
self.setInterval("funB()", 1000);
function funA() {
while (true) {
}
}
function funB() {
console.log('B');
}
实际这边的funA与funB都是充当回调函数被调用,以实现异步执行。大部分情况下我们的异步也是这么实现,但是看一下结果
输出结果是这样的:
在第七秒时停止了打印。(这里由于计时创建等开销,不是第八秒停止打印)
当funA起来后阻塞了主线程导致B被卡死。到这里不难看出来第一个示例是由于大部分时间CPU是处于空闲状态,导致A,B都能运行,看似同时运行其实不然。
再来看一下这样一段代码:
var worker = new Worker("worker.js");
worker.postMessage(null);
worker.onmessage = function (evt) {
console.log('result = ' + evt.data);
}
function consoleInMainThread() {
console.log('console In Main Thread');
}
self.setInterval("consoleInMainThread()", 1000);
worker.js内如如下:
onmessage = function (evt) {
sleep(5);
postMessage(new Date());
}
function sleep(second) {
var date = new Date();
var currentDate = null;
do {
currentDate = new Date();
} while (currentDate - date <= second*1000);
}
看一下输出:
主线程在不间断打印信息,Worker线程在前5秒也是处于运行状态
很显然此处的Worker实现了预期的并发执行。
总结:没有特殊需求情况下JS中较大部分仍然是单线程运行,只是以队列的方式将需要执行的任务按约定的时间进行顺序执行,
值得一提的是,单线程运行并非是代码的单线程运行而是任务的单线程运行,当然多线程的并发执行
还有其他的实现这里不在阐述。此博文仅帮助理解异步与并发两个概念。