JavaScript 异步编程


JavaScript 异步编程

JavaScript 异步编程是指一种非同步操作执行的编程方式。我们编写的 JavaScript 代码执行通常是逐行执行,同步执行。但有些异步操作,例如网络请求、定时器等,需要等待一段时间才能完成,如果我们采用同步方式编写程序,就需要一直等待异步操作完成,这样会导致浏览器界面假死,不够流畅。因此,我们需要一种不阻塞主线程的异步编程方式。

回调函数

回调函数是 JavaScript 异步编程中最常见的编程方式。我们将需要异步执行的代码封装在一个函数中,然后将这个函数作为回调函数传递给异步函数,在异步操作完成时,异步函数将调用回调函数。例如,我们可以使用 XMLHttpRequest 发起一个网络请求,代码如下:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.example.com/api/data');
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    const data = JSON.parse(xhr.responseText);
    callback(data);
  }
};
xhr.send();

在上述代码中,xhr.onreadystatechange 是 XMLHttpRequest 对象的回调函数,当网络请求完成时,浏览器将调用该函数。在回调函数中,我们可以处理请求返回的数据。

Promise

Promise 是 ES6 引入的一种更加优雅的异步编程方式。Promise 对象表示一个异步操作的最终完成或失败,并返回一个值。Promise 对象是一个构造函数,使用时需要 new 实例化,然后调用 then 方法注册回调函数。例如,我们可以使用 fetch 发起网络请求,并使用 Promise 处理响应数据,代码如下:

fetch('https://www.example.com/api/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => console.error(error));

在上述代码中,fetch 返回一个 Promise 对象,我们使用 then 方法注册当请求返回数据时的回调函数,使用 catch 方法注册当请求失败时的回调函数。

async 和 await

async 和 await 是 ES8 引入的一种更加简洁、易于理解的异步编程方式。async 函数是 Promise 的语法糖,可以让我们更加方便地使用 Promise。在 async 函数中,我们可以通过使用 await 关键字来等待异步操作完成,这样代码更加直观、易读。例如,我们可以使用 async 和 await 发起网络请求,并处理响应数据,代码如下:

async function getData() {
  try {
    const response = await fetch('https://www.example.com/api/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

getData();

在上述代码中,getData 是一个 async 函数,它使用 await 关键字等待 fetch 异步操作完成,并使用 try…catch 处理异常情况。

总结

JavaScript 异步编程是当下最常见的编程方式,理解异步编程的核心思想对于编写高效、优雅的 JavaScript 代码至关重要。除了回调函数、Promise、async 和 await,还有诸如事件、生成器等异步编程方式,通过不断学习和实践,我们可以更加熟练地掌握这些技术,并编写出更加高效的异步代码。