PHP前端开发

JS:承诺还是回调?

百变鹏仔 3天前 #JavaScript
文章标签 回调

理解 javascript 中的 promise 与 callback

认证测试的关键问题和解答

  1. 什么是回调函数,它与常规函数有何不同?

  2. 与回调相比,promise 如何提高代码可读性并管理异步操作?

  3. promise 的主要状态是什么,它们如何在这些状态之间转换?

  4. 如何使用 promise 处理错误,这与使用回调的错误处理相比如何?

  5. promise.all 和 promise.race 有什么区别,什么时候会使用它们?

  6. async/await 语法如何简化 promises 的使用,以及使用 wait 的规则是什么?


介绍

在 javascript 不断发展的环境中,有效管理异步操作是构建高性能 web 应用程序的关键。虽然回调是最初的方法,但 promises 引入了一种更加结构化和可读的方法来处理异步任务。本博客深入探讨了使用 promise 与回调的复杂性,假设您已经对这些概念有基本的了解。

promise 相对于回调的好处

提高可读性和可维护性

回调虽然有效,但通常会导致称为“回调地狱”的深层嵌套结构,使代码难以阅读和维护。

回调地狱的例子:
fetchdata(function(response1) {  fetchmoredata(response1, function(response2) {    fetchevenmoredata(response2, function(response3) {      console.log(response3);    });  });});
通过 promise 进行改进:
fetchdata()  .then(response1 => fetchmoredata(response1))  .then(response2 => fetchevenmoredata(response2))  .then(response3 => console.log(response3))  .catch(error => console.error(error));
错误处理

使用回调,错误处理可能会变得很麻烦,因为您需要传递错误对象并在每个级别处理它们。

使用回调处理错误:
function fetchdata(callback) {  settimeout(() => {    if (/* error condition */) {      callback(new error('an error occurred'), null);    } else {      callback(null, 'data');    }  }, 1000);}fetchdata((error, data) => {  if (error) {    console.error(error);  } else {    console.log(data);  }});
使用 promise 进行错误处理:
function fetchdata() {  return new promise((resolve, reject) => {    settimeout(() => {      if (/* error condition */) {        reject(new error('an error occurred'));      } else {        resolve('data');      }    }, 1000);  });}fetchdata()  .then(data => console.log(data))  .catch(error => console.error(error));
高级 promise 方法

promise.all

当你需要等待多个异步操作完成才能继续时,promise.all 非常有用。

例子:
const promise1 = promise.resolve(3);const promise2 = 42;const promise3 = new promise((resolve, reject) => {  settimeout(resolve, 100, 'foo');});promise.all([promise1, promise2, promise3]).then(values => {  console.log(values); // [3, 42, "foo"]});
promise.race

当你需要最快操作的结果时,promise.race 很有用。

例子:
const promise1 = new promise((resolve, reject) => {  settimeout(resolve, 500, 'one');});const promise2 = new promise((resolve, reject) => {  settimeout(resolve, 100, 'two');});promise.race([promise1, promise2]).then(value => {  console.log(value); // "two"});
使用 async/await 简化异步代码

async/await 语法允许您编写看起来同步的异步代码,增强可读性并降低链接 promise 的复杂性。

例子:
async function fetchData() {  return 'data';}async function processData() {  try {    const data = await fetchData();    console.log(data);  } catch (error) {    console.error(error);  }}processData();
结论

虽然回调为 javascript 中处理异步操作奠定了基础,但 promise 显着提高了异步代码的可读性、可维护性和错误处理能力。了解如何以及何时有效地使用这些工具对于现代 javascript 开发至关重要。借助 promises 和 async/await 语法,开发人员可以编写更清晰、更易于管理的代码,为更强大的应用程序铺平道路。