MST

星途 面试题库

面试题:网络编程中异步编程的回调地狱及Promise解决方案 - 中等难度

在网络编程的异步场景下,假设你需要依次执行三个异步操作A、B、C,每个操作都通过回调函数获取结果。请用回调函数的方式实现这个流程,并指出可能出现回调地狱的原因。然后,使用Promise将其重构,说明Promise相较于回调函数在这种场景下的优势。
24.5万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

回调函数方式实现

function asyncOperationA(callback) {
    setTimeout(() => {
        callback('Result of A');
    }, 1000);
}

function asyncOperationB(callback) {
    setTimeout(() => {
        callback('Result of B');
    }, 1000);
}

function asyncOperationC(callback) {
    setTimeout(() => {
        callback('Result of C');
    }, 1000);
}

asyncOperationA((resultA) => {
    console.log(resultA);
    asyncOperationB((resultB) => {
        console.log(resultB);
        asyncOperationC((resultC) => {
            console.log(resultC);
        });
    });
});

回调地狱的原因

  1. 嵌套过深:随着异步操作的增多,回调函数会层层嵌套,代码变得越来越难以阅读和维护。例如上述代码如果有更多异步操作需要依次执行,嵌套会更深。
  2. 错误处理复杂:在嵌套的回调中,错误处理变得繁琐,每个回调函数都需要单独处理错误,难以统一管理。

Promise重构

function asyncOperationA() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('Result of A');
        }, 1000);
    });
}

function asyncOperationB() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('Result of B');
        }, 1000);
    });
}

function asyncOperationC() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('Result of C');
        }, 1000);
    });
}

asyncOperationA()
  .then(resultA => {
        console.log(resultA);
        return asyncOperationB();
    })
  .then(resultB => {
        console.log(resultB);
        return asyncOperationC();
    })
  .then(resultC => {
        console.log(resultC);
    });

Promise相较于回调函数的优势

  1. 代码可读性提高:通过.then链式调用,避免了回调函数的层层嵌套,使代码结构更加清晰,易于理解和维护。
  2. 统一的错误处理:可以通过.catch统一处理整个Promise链中的错误,而不需要在每个回调函数中单独处理,简化了错误处理逻辑。