前端面经每日一题Day19
如何解决异步回调地狱?
异步回调地狱是异步编程常见的问题。在处理多个需要按照顺序执行的异步操作时,每个操作结果都是下一个操作的输入,代码会变成多层嵌套的回调函数。
补充回调函数:函数A作为参数传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。
1.promise方法
ES6
引入的方法,将嵌套的回调转化为链式的then调用,从而避免回调地狱。
function LoadData(){
return new Promise((resolve,reject)=>{
settimeout(()=>>{
console.log('Loading data...');
resolve('loading data')
})
})
}
function processData(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Processing data...');
resolve(`${data} processed`);
}, 2000);
});
}
function saveData(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Saving data...');
resolve(`${data} saved`);
}, 2000);
});
}
loadData()
.then(data => processData(data))
.then(processedData => saveData(processedData))
.then(savedData => {
console.log('Data flow complete:', savedData);
})
.catch(error => {
console.error('An error occurred:', error);
});
2.async/awit
asynce/await
是基于promise的语法糖,使异步代码看起来像同步代码。
1.async function dataFlow() {
try {
const data = await loadData();
const processedData = await processData(data);
const savedData = await saveData(processedData);
console.log('Data flow complete:', savedData);
} catch (error) {
console.error('An error occurred:', error);
}
}
dataFlow();
2.async function asyncFlow() {
const data = await loadData();
const processedData = await processData(data);
const result = await saveData(processedData);
return result;
}
asyncFlow().then(result => {
console.log(result); // 输出: 'data loaded processed saved'
});
3.生成器
生成器是一个特殊的函数(在函数名前面加一个*
号),用来解决异步编程的回调地狱问题。不常用。
async/await
具体该怎么用?
async funcion getdata(){
let data=await getdatasecond()
console.log(data)
}
funcion getdatasecond(){
return new Promise((resolve,reject)=>{
settiemout(()=>{
resolve(data)
},2000)
}
}
promise和async/await的关系?
- promise 解决异步回调地狱的措施,提供链式调用能力,将嵌套的回调转化为链式的then调用。
- async/await是基于promise的语法糖。async 关键字用于声明一个异步函数,
await
关键字用于等待一个 Promise 完成,并返回 Promise 解决(resolve)的值。
Promise的出现解决了传统callback函数导致的“地狱回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。async await与Promise一样,是非阻塞的(异步)。
defer和async的区别?
defer属性和async属性都只适用于外部脚本文件:表示立即下载,延迟执行。 defer与async的区别是: defer要等到整个页面正常渲染结束,才会执行。—-等待页面渲染后在执行。 async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。—-下载完成立即执行,可能会阻塞页面。