1.js单线程
大家都知道,JavaScript的一大特点就是单线程,也就是说,在同一个时间节点内,只能够执行一个任务。 在这里又会涉及到一些js宏任务与微任务的问题。
宏任务就是包括 script整体代码、setTimeout、setInterval I/O UI交互事件 postMessage MessageChannel setImmediate(Node.js 环境)
而微任务是宏任务执行完毕后才会执行的任务,类似于Promise.then、 Object.observe、 MutationObserver、 process.nextTick(Node.js 环境)
在js整个执行机制中是如图这样的流程
让我们来看段代码,相信大部分都可以说出执行的结果
console.log("1");
process.nextTick(function () {
console.log("2");
});
setTimeout(function () {
console.log("3");
process.nextTick(function () {
console.log("4");
});
}, 0);
new Promise(function (resolve,obj) {
console.log("5");
resolve()
}).then(function () {
console.log("6");
});
console.log("7");
2.让其异步
这里举个例子,有时候我们在使用setTimeout时候,会遇到其执行根本不是按照所指定的时间执行,若在宏任务对列中存在类似于循环这样的东西(或者是非常严重的网络问题时),就会导致setTimeout执行失败或者是远远出指定的时间。看一下下方的实例。
这里执行所花费的时间远远不止3秒。 那再来看一下网络问题呢,这里在后台中选择slow 3G,也会导致这样的问题。这里就需要用到了js单线程的异步操作。
(1)这里使用了回调函数的方式。
function f1(){
console.log('1');
f2()
}
function f2(){
setTimeout(function(){
console.log('2');
f3()
},1000)
}
function f3(){
console.log('3')
}
(2)事件发布/订阅
class add {
constructor (...arr){
this.funcArr = [...arr] }
next () {
const fn = this.funcArr.shift()
if (typeof fn === 'function') fn() }
run () {
this.next() } }
const aa = new add(f1、f2、f3)
function f1(){
console.log('1');
aa.b=next()
}
function f2(){
console.log('2');
aa.b=next()
}
function f3(){
console.log('3');
aa.b=next()
}
(3)new 一个promise实例
function fn() {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log('11');
resolve();
})
})
}
function fn2() {
console.log('2')
}
fn().then(() => {
fn2()
})