MST

星途 面试题库

面试题:JavaScript IIFE在复杂异步场景中的优化

假设有一个复杂的异步操作序列,包含多个相互依赖的异步任务,在ES6之前的环境下,如何使用IIFE结合回调函数或Promise来优化异步代码结构,避免回调地狱,并详细阐述优化思路。
37.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

使用IIFE结合回调函数优化

  1. 优化思路
    • 回调地狱通常是由于多层嵌套的回调函数导致代码可读性和维护性变差。使用IIFE(立即执行函数表达式)可以将每个异步操作封装在一个独立的函数中,减少嵌套层级。
    • 每个IIFE接收前一个异步操作的结果作为参数,这样可以更清晰地处理异步任务间的依赖关系。
  2. 示例代码
// 模拟异步操作
function asyncOperation1(callback) {
    setTimeout(() => {
        callback('result1');
    }, 1000);
}
function asyncOperation2(input, callback) {
    setTimeout(() => {
        callback(`result2 based on ${input}`);
    }, 1000);
}
function asyncOperation3(input, callback) {
    setTimeout(() => {
        callback(`result3 based on ${input}`);
    }, 1000);
}

// 使用IIFE优化
(function step1() {
    asyncOperation1((result1) => {
        (function step2() {
            asyncOperation2(result1, (result2) => {
                (function step3() {
                    asyncOperation3(result2, (result3) => {
                        console.log(result3);
                    });
                })();
            });
        })();
    });
})();

使用IIFE结合Promise优化

  1. 优化思路
    • Promise将异步操作表示为一个状态机,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
    • 通过将每个异步操作封装成一个返回Promise的函数,利用.then()方法来链式调用这些Promise,避免了回调地狱。IIFE可以用来启动这个Promise链。
  2. 示例代码
// 模拟异步操作,返回Promise
function asyncOperation1() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('result1');
        }, 1000);
    });
}
function asyncOperation2(input) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(`result2 based on ${input}`);
        }, 1000);
    });
}
function asyncOperation3(input) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(`result3 based on ${input}`);
        }, 1000);
    });
}

// 使用IIFE结合Promise优化
(function () {
    asyncOperation1()
      .then((result1) => asyncOperation2(result1))
      .then((result2) => asyncOperation3(result2))
      .then((result3) => {
            console.log(result3);
        });
})();

在ES6之前的环境下,使用Promise需要引入Polyfill(如es6 - promise库)来支持Promise的功能。而无论是使用回调函数结合IIFE还是Promise结合IIFE,核心都是通过合理的封装和链式调用,使异步代码结构更清晰,避免回调地狱的产生。