- js是单线程的工作机制,不过浏览器是多线程的,所以不要担心单线程的js是不是落后,反正有浏览器帮衬。
- 浏览器有个叫
web worker
的东西,可以让浏览器开出一个Worker线程,通过接受发送消息和主线程交互,并且和主线程不冲突的执行。 web worker
的讲解详情请翻看本站其他文章讲解- 几乎现在的主流语言都有同步和异步问题,那么js的异步有哪些?
- 浏览器从开始执行遇到script会开启一个宏任务。遇到setTimeour也会开启一个宏任务。遇到ajax请求开启的是一个微任务。只有当一个宏任务所有的同步代码和所有微任务全部代码执行完毕后,浏览器才会开始下一个宏任务。这里的setTimeout属于下一个宏任务。
代码举例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
// Promise是属于script这个宏任务的,和console.log一样都是属于Promise的
const prom = new Promise(function (ret, rej) {
console.log(3)
const ajax = new XMLHttpRequest();
ajax.onreadystatechange=function(){
ret(4)
}
ajax.open("GET","https://search-merger-ms.juejin.im/v1/search?query=ajax&page=0&raw_result=false&src=web",true);
ajax.send();
console.log(5)
setTimeout(() => {
console.log(6)
}, 0)
})
// prom.then()是一个微任务,所以都是属于script这个宏任务,则按照先后顺序执行
prom.then(res => {
console.log(res)
setTimeout(() => {
console.log(7)
})
})
setTimeout(() => {
console.log(8)
})
console.log(9)
// 1 3 5 9 4 2 6 8 7
```
- 应用举例:
```javascript
/*
需求:
obj.eat('a') //立即打印'a'
obj.stop(3000).eat('a') //延迟3秒后打印a
*/
class laz {
constructor(name) {
this.tasks = []
setTimeout(() => {
this.next()
},0)
}
next () {
let task = this.tasks.shift()
// 如果task为真,则执行task();如果task为假,则不执行task()
task && task()
}
eat(val) {
const task = (val => () => {
console.log(val)
this.next()
})(val)
this.tasks.push(task)
return this
}
stop (time) {
const task = (time => () => {
setTimeout(() => {
console.log(time)
this.next()
},time)
})(time)
this.tasks.push(task)
return this
}
}
const obj = new laz()
obj.eat('a')
obj.stop(3000).eat('a')
JS异步执行如何工作的
Share