JS学习-async/await

async/await

  1. 它保证函数的返回值为 promise。
  2. 用更少的.then()块来封装代码,同时它看起来很像同步代码

注意:可能会因为大量await的promises相继发生而变慢。

async关键字

使用 async 关键字,把它放在函数声明之前,使其成为 async function。

let hello = async function() {
	return "Hello"
};
//let hello = async () => { return "Hello" };
hello();  //Promise { <state>: "fulfilled", <value>: "Hello" }

await关键字

await 只在异步函数里面才起作用。

promise & async/await

//promise
fetch('coffee.jpg').then(response => response.blob())
.then(myBlob => {
	let image = document.createElement('img');
	image.src = URL.createObjectURL(myBlob);
	document.body.appendChild(image);
}).catch(e => {
	console.log('an error with fetch img: ' + e.message);
});
//async/await
async function fetchImg(){
	try{
		let myFetch = await fetch('coffee.jpg');
		let myBlob = await myFetch.blob();
		let image = document.createElement('img');
		image.src = URL.createObjectURL(myBlob);
		document.body.appendChild(image);
	}catch(e){
		console.log('an error with fetch img: ' + e);
	}
}
//promise + async/await
(async function fetchImg(){
	let myFetch = await fetch('coffee.jpg');
	return await myFetch.blob();
})().then(blob=>{
	let image = document.createElement('img');
	image.src = URL.createObjectURL(myBlob);
	document.body.appendChild(image);
}).catch(e => {
	console.log('an error with fetch img: ' + e.message);
});

async/await 的缺点

await 关键字会阻塞其后的代码,直到promise完成,就像执行同步操作一样。

这意味着您的代码可能会因为大量awaitpromises相继发生而变慢。每个await都会等待前一个完成,而你实际想要的是所有的这些promises同时开始处理(就像我们没有使用async/await时那样)。

有一种模式可以缓解这个问题——通过将 Promise 对象存储在变量中来同时开始它们,然后等待它们全部执行完毕。

function timeoutPromise(time) {
	return new Promise((resolve, reject) => {
		setTimeout(()=>{
			resolve("done");
		}, time);
	});
};

let startTime = Date.now();
timeTest().then(() => {
	let timeTaken = Date.now() - startTime;
	alert("Time taken in milliseconds: " + timeTaken);
})

//slow:大约是9s
async function timeTest() {
	await timeoutPromise(3000);
	await timeoutPromise(3000);
	await timeoutPromise(3000);
}
//fast:大约是3s
async function timeTest() {
	const timeoutPromise1 = timeoutPromise(3000),timeoutPromise2 = timeoutPromise(3000),timeoutPromise3 = timeoutPromise(3000);
	await timeoutPromise1;
	await timeoutPromise2;
	await timeoutPromise3;
}
//or:大约是3s
await Promise.all([timeoutPromise(3000),timeoutPromise(3000),timeoutPromise(3000)]);

旧式异步回调的缺点

  • 嵌套回调可能很麻烦且难以阅读(即“回调地狱”)
  • 每层嵌套都需要故障回调,而使用promises,您只需使用一个.catch()代码块来处理整个链的错误。
  • 异步回调不是很优雅。
  • Promise回调总是按照它们放在事件队列中的严格顺序调用;异步回调不是。
  • 当传入到一个第三方库时,异步回调对函数如何执行失去完全控制。
posted @ 2022-08-12 13:35  ~LemonWater  阅读(73)  评论(0编辑  收藏  举报