宏任务和微任务
resolve(传的参数)标记成功,会调用promise.then
练习网站:
关于promise深入理解太长没来及看 博客文章:
promise本身是同步的,then/catch的回调函数是异步的
直接做题加深理解
点常见面试题
- 宏任务和微任务
- 这个是前端pink老师
- 事件循环eventloop
- 宏任务和微任务
- 这个是晓舟报告 up主
- 常见面试题
- 题目1.
- 题目2.
- 题目3 3-6
- 题目4.
- 题目5:
- 题目6:
- 注意:
- 题目7:晓舟报告 ❌
- 题目8 ❌
- 题目9:
- 题目10 ❌
- 题目10
- 总结
- 题目11
- 其他题目
- 总结
- 立超老师
这个是前端pink老师
事件循环eventloop
视频地址:
有些任务是耗时的,会阻塞代码的运行。比如中间有定时器,鼠标点击事件等
因此引出同步任务和异步任务
js执行栈的代码立即执行 返回结果
异步任务放到宿主环境中,等待正确的时机,推送到任务队列中【里面放着回调函数】
总结:
- js是单线程,防止代码阻塞。任务分为同步任务和异步任务
- 同步任务给js引擎执行,异步任务交给宿主环境【多线程】
- 同步代码放到执行栈中,异步代码等待时机成熟推送到任务队列中排序
- 执行栈执行完毕,会去任务队列中查看是否有异步代码,有就送到执行栈中执行,反复循环查看执行,这个过程叫事件循环。
宏任务和微任务
es5后引入了promise,不需要浏览器,js引擎也可以发起异步任务了
执行顺序
这个是晓舟报告 up主
视频链接
微任务在DOM渲染前,宏任务在DOM渲染后,所以微任务比宏任务先执行
执行顺序:
async和await
async/await会返回一个promise对象
// async function fun(){
// return 1
// }
等价于
function fun() {
return new Promise(resolve => {
resolve(1)
})
}
fun().then(data => {
console.log(data)
})
//这样才可以获取值为1
let p1 = new Promise(resolve => {
resolve(1)
})
let p2 = new Promise(resolve => {
resolve(2)
})
async function fun() {
let a = await p1
let b = await p2
console.log(a, b) //1,2
}
fun()
await之后的代码可以理解为then中执行的代码
async function fun1() {
let data = await fun2()
console.log(data) //then中执行的代码
}
async function fun2() {
console.log(200)
return 100
}
fun1()
//200 100
例子-----后面题目也有这个例子:
总结:
常见面试题
题目1.
直接理解
const myPromise = Promise.resolve(Promise.resolve('Promise'))
function funcOne() {
setTimeout(() => console.log('Timeout 1!'), 0)
myPromise.then(res => res).then(res => console.log(`${res} 1!`))
console.log('Last line 1!')
}
async function funcTwo() {
const res = await myPromise
console.log(`${res} 2!`)
setTimeout(() => console.log('Timeout 2!'), 0)
console.log('Last line 2!')
}
funcOne()
funcTwo()
//输出结果
Last line 1!
Promise 2!
Last line 2!
Promise 1!
Timeout 1!
Timeout 2!
题目2.
const myPromise = Promise.resolve(Promise.resolve('Promise11111!'))
function funcOne() {
myPromise.then(res => res).then(res => console.log(res + 'cc'))
setTimeout(() => console.log('Timeout!111'), 0)
console.log('Last line!111111')
}
async function funcTwo() {
const res = await myPromise
console.log((await res) + 'res')
setTimeout(() => console.log('Timeout!222'), 0)
console.log('Last line!2222222')
}
funcOne()
funcTwo()
//输出结果
Last line!111111
Promise11111!cc
Promise11111!res
Last line!2222222
Timeout!111
Timeout!222
题目3 3-6
题目3- 6来源于b站https://www.bilibili.com/video/BV1xe4y147ZB/?
结果是 3 2 1
resolve只是标记成功 里面的状态改变了 ,还是会继续往下执行
题目4.
结果是 11 14 12 15 13
题目5:
结果是:2 3 6 P2 P1 1 4 5
题目6:
结果是:
注意:
await是右结合,右边代码执行完了才会执行下面的函数。await之后的代码都是微任务 ,放到异步队列中!!!
题目7:晓舟报告 ❌
视频来源
setImmediate(() => {
console.log(1)
})
console.log(2)
setTimeout(() => {
console.log(3)
}, 0)
setTimeout(() => {
console.log(4)
},100)
console.log(5)
new Promise(resolve => {
console.log(6)
resolve()
}).then(() => {
console.log(7)
})
process.nextTick(() => {
console.log(8)
})
//
2
5
6
8
7
3
1
4
题目8 ❌
// 宏任务队列 1
setTimeout(() => {
// 宏任务队列 2.1
console.log('timer_1')
setTimeout(() => {
// 宏任务队列 3
console.log('timer_3')
}, 0)
new Promise(resolve => {
resolve()
console.log('new promise')
}).then(() => {
// 微任务队列 1
console.log('promise then')
})
}, 0)
setTimeout(() => {
// 宏任务队列 2.2
console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')
//
========== Sync queue ==========
timer_1
new promise
promise then
timer_2
timer_3
疑问:宏定时器2比定时器3先输出
题目9:
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
//
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
题目10 ❌
console.log('1')
setTimeout(function () {
console.log('2')
process.nextTick(function () {
console.log('3')
})
new Promise(function (resolve) {
console.log('4')
resolve()
}).then(function () {
console.log('5')
})
})
process.nextTick(function () {
console.log('6')
})
new Promise(function (resolve) {
console.log('7')
resolve()
}).then(function () {
console.log('8')
})
setTimeout(function () {
console.log('9')
process.nextTick(function () {
console.log('10')
})
new Promise(function (resolve) {
console.log('11')
resolve()
}).then(function () {
console.log('12')
})
})
//结果
1
7
6
8
2
4
3
5
9
11
10
12
process.nexTick在不同浏览器执行标准不一样
题目10
总结
- 宏任务里如果有宏任务,不会执行里面的那个宏任务,而是被丢进任务队列后面,所以会最后执行。
- 一个宏任务执行完才会去执行另外一个宏任务
- async函数返回值是promise对象
题目11
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4)));
Promise.resolve().then(() => console.log(5));
setTimeout(() => console.log(6));
console.log(7);
//
1
7
3
5
2
6
4
其他题目
其他题目
总结
- 宏任务里如果有宏任务,不会执行里面的那个宏任务,而是被丢进任务队列后面,所以会最后执行。
- 一个宏任务执行完才会去执行另外一个宏任务
- async函数返回值是promise对象,await后面的代码是异步微任务
立超老师
博客:
// function func() {
// return new Promise(resolve => resolve(10))
// }
// 等价于
async function func() {
return 10
}
func().then(console.log)
// func().then(console.log)
// func().then(num=>console.log(num)) //10
- async声明的异步函数,它的返回值会自动包装成promise
- async声明的异步函数中可以使用await来调用其他异步函数