接口模拟
onMounted 中 setTimeout 模拟接口请求,默认为异步执行
<template>
----------
</template>
<script setup>
import { ref, reactive, onBeforeMount, onMounted } from "vue";
onMounted(() => {
event3();
event2();
event4();
event1();
});
const event1 = () => {
setTimeout(() => {
console.log("time1");
}, 1000);
};
const event2 = () => {
setTimeout(() => {
console.log("time2");
}, 2000);
};
const event3 = () => {
setTimeout(() => {
console.log("time3");
}, 3000);
};
const event4 = () => {
setTimeout(() => {
console.log("time4");
}, 4000);
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
执行结果
使用 async 部分同步执行
onMounted( async () => {
event3();
event2();
await event4();
await event1();
});
const event1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event1");
}, 1000);
});
};
const event4 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event4");
}, 4000);
});
};
执行结果
使用 async 全部同步执行
onBeforeMount(async () => {
await event3(); //await
await event2(); //await
await event4(); //await
await event1(); //await
});
const event1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event1");
}, 1000);
});
};
const event2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event2");
}, 2000);
});
};
const event3 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event3");
}, 3000);
});
};
const event4 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log("event4");
}, 4000);
});
};
执行结果
js单线程为什么支持异步执行
JavaScript执行线程本身是单线程,但是整个浏览器不是单线程的。V8引擎在检测到异步调用,如setTimeout等WebAPIs调用后,会将其交给浏览器的其他线程进行执行处理,完了后再通过事件循环机制(event loop)返回执行线程执行回调。
事件循环和回调队列
tip:图片来源网络
如图所示,浏览器V8引擎遇到同步任务会直接进入调用栈执行,遇到异步交给由浏览器的Web Apis来执行,执行完之后将回调添加到调用队列(任务队列),等调用栈的任务清空后执行调用队列事件,来实现 event loop。
codesandbox访问
总结
- async + await 改为同步
- 方法必须 resolve 否则中下面断执行