前言
在很长一段时间里,因为是外行人,我看到js里面的同步/异步的概念,还一直以为 同步 就是多任务并行,而 异步 才是顺序执行,等到今天正儿八经地看下js的异步模型,这才浅浅了解
异步模式
异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。
同步按你的代码顺序执行,异步不按照代码顺序执行(不代表并行),异步的执行效率更高。
在遇到一些耗时时间长的事件时,可以利用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情;
但这样子主线程不清楚子线程的情况,不处于原先的一个同步状态。
回调函数
回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。
// setTimeout(JavaScript 函数, 等待的毫秒数)
setTimeout(function () {
document.getElementById("demo").innerHTML="RUNOOB!";
}, 3000);
Promise
Promise 的异步性体现在其回调管理机制而非自身实现异步
同步执行部分
Promise 构造函数内的executor函数(即new Promise(fn)中的fn)是同步执行的,例如:
new Promise(resolve => {
console.log(1); // 同步代码
resolve(3);
});
console.log(2);
// 输出顺序:1 → 2
异步回调部分
通过.then()
注册的回调函数会被放入微任务队列(Microtask Queue),等待当前执行栈清空后才会执行:
new Promise(resolve => {
console.log(1);
resolve(3);
}).then(num => console.log(num));
console.log(2);
// 输出顺序:1 → 2 → 3
所以在这里有点进一步加深对 异步 的理解,即 异步 ≠ 并行:
- 异步:代码执行权交还主线程,回调延迟执行(JS 单线程特性)
- 并行:多线程同时执行(如 Web Worker)
asnyc
在JavaScript中,async
是一个关键字,用于声明一个异步函数。当你使用async
关键字定义一个函数时,这个函数就会成为一个异步函数。异步函数的主要特点是它内部可以使用await
关键字来等待一个异步操作的完成,而不会阻塞代码的执行。
async function myAsyncFunction() {
return 'Hello, world!';
}
myAsyncFunction().then(result => {
console.log(result); // 输出: Hello, world!
});
await
使用**await
**关键字:在异步函数内部,你可以使用await
关键字来等待一个Promise
的解决(resolve)或拒绝(reject)。await
会暂停异步函数的执行,直到等待的Promise
完成,然后继续执行异步函数并返回解决的值。如果Promise
被拒绝,则await
表达式会抛出一个异常。
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}