从回调函数到JavaScript异步编程

作者:J.sky · 发表于:
2023-04-16T17:58:52.000000Z
· 更新于:
2023-08-13T22:54:57.577618Z
· Tag: JavaScript

异步编程是JavaScript中的一个重要概念。为了理解异步编程,首先需要了解同步编程的工作原理。在同步编程中,代码按行执行,每行必须在下一行开始之前完成执行。当处理长时间运行的任务或需要等待外部资源时,这可能会导致性能问题。 JavaScript中的异步编程允许非阻塞代码执行,这意味着代码可以在等待长时间运行的任务或外部资源时继续运行。这是通过使用回调函数、Promise和async/await实现的。 回调函数是作为参数传递给其他函数并在原始函数完成其任务时执行的函数。Promise是表示异步操作的最终完成或失败的对象,并允许编写更可读和可维护的代码。 async/await是一种新的语法,通过使用关键字“async”和“await”来处理Promise,从而实现更可读和可维护的异步代码。

回调

先从一个回调函数开始:

function cb(callback){
    callback()
}
cb(()=>{console.log("callback函数")})

回调函数的参数中会有一个函数的参数。

下面的这个回调函数,调用了一个自定义的函数:

function cb1(callback){
    const rest = {name:"callbackdata"}
    callback(rest)
}

function print_rest(rest){
    console.log(rest)
}

cb1(print_rest)

第三个回调函数加入了setTimeout

function fetchData(name, callback) {
    setTimeout(() => {
        const data = {name: name};
        callback(data);
    }, 3000);
}

fetchData("one", (data) => {
    console.log(data);
});

这会使代码运行3秒后打印数据。其实最开始的时候我也不太理解回调,运行一下这三个函数试试理解一下。 在此示例中,fetchData函数使用setTimeout函数模拟从外部资源获取数据,以延迟执行回调函数1秒钟。fetchData函数接受一个回调函数作为参数,在可用时使用获取的数据执行该函数。 回调函数可能很快变得难以管理,并导致回调地狱,其中嵌套的回调函数变得难以阅读和维护。Promise可以通过允许编写更可读和可维护的代码来帮助缓解此问题.

Promise

以下是使用Promise处理JavaScript中的异步代码的示例:

function fetchData_a() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = {name: "two"};
            resolve(data);
        }, 2000);
    });
}

fetchData_a()
    .then((data) => {
        console.log(data);
    })
    .catch((error) => {
        console.error(error);
    });

在此示例中,fetchData_a函数返回一个Promise,该Promise在可用时解析为获取的数据。使用then方法处理已解析的Promise并将数据记录到控制台.使用catch方法处理可能在Promise执行期间发生的任何错误。

async/await

async/await是一种新的语法,通过使用关键字“async”和“await”来处理Promise,从而实现更可读和可维护的异步代码. 以下是使用async/await处理JavaScript中的异步代码的示例:

function fetchData_b() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = {name: "three"};
            resolve(data);
        }, 1000);
    });
}

async function getData() {
    try {
        const data = await fetchData_b();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}

getData();

在此示例中,fetchData_b函数返回一个Promise,该Promise在可用时解析为获取的数据。getData函数声明为async,并使用await关键字处理已解析的Promise并将数据记录到控制台. 使用try和catch块处理可能在Promise执行期间发生的任何错误. 总之,异步编程在JavaScript中是一个重要的概念,对于编写性能良好且易于维护的代码非常重要。通过使用回调函数、Promise和async/await,开发人员可以编写非阻塞代码并处理长时间运行的任务和外部资源.