Fetch API 是 AJAX 的新旧版本
如果您大约十年前开始开发生涯,您可能知道在我们的 Web 应用程序中使用 AJAX 有多复杂。然而,现在我们都知道,现代原生 JavaScript 为我们带来了一些强大的功能,包括 Fetch API——一种无需重新加载页面即可从服务器获取数据的更简便的方法。
AJAX(异步 JavaScript 和 XML)这一编程概念出现于 20 世纪 90 年代末,它允许在不完全刷新页面的情况下更新部分 HTML DOM,从而使我们的项目更具动态性和交互性。这得益于XMLHttpRequest API(由 Internet Explorer 5 于 1998 年引入)。顾名思义,该 API 旨在通过 HTTP 获取 XML 数据,后来又增加了对 JSON、HTML 和纯文本等其他格式的支持。但当时使用 XMLHttpRequest 非常麻烦,因此一些库(例如 jQuery(创建于 2006 年))对其进行了抽象,使其更易于使用。
随着 JS 的发展,Fetch API 于 2015 年推出,并已成为当今处理数据请求的标准。Fetch API 现在也可以在 Node.js 端运行(版本 21),您可以在LogRocket 的这篇博文和Node.js 官方公告中了解到这一点。
在我们深入了解 Fetch API 之前,让我们先了解一些 JavaScript 概念(有关完整解释,请参阅本文末尾的参考资料):
JavaScript 中的异步是什么?
默认情况下,JavaScript 作为单线程编程语言同步运行,这意味着一个进程必须完成才能启动另一个进程。但是,有一些方法可以通过使代码异步来确保 JS 中的进程同时协同工作。
为了便于理解,我们假设你去披萨店订披萨。服务员接你的订单并送到厨房。同步情况下,服务员必须等到你的披萨烤好后再送过来,然后再去给另一位顾客接订单,等待他们的披萨准备好,如此循环往复。如你所见,这不是一个好方法。另一方面,异步情况下,服务员无需等待披萨准备好再送往下一位顾客,他们只需简单地前往下一位顾客那里接订单,并在披萨准备好后送往厨房即可。这就是同步系统和异步系统的区别。
回调函数
在 JS 中处理异步代码最古老、最常见的方法之一是使用回调函数。JS中有一个概念,就是说一个函数“等待将来运行,而不是现在”。
回调函数是作为参数传递给另一个函数的函数,然后在外部函数内部调用该函数来完成某种例程或操作。 - MDN
实现这一点的方法有很多,例如,当我们需要获取一些外部数据并等待服务器响应后再执行其他操作时。这时 AJAX 就派上用场了,jQuery 通过使用其库的$.ajax()
方法让这一切变得简单。
但是当我们需要嵌套回调来执行不同的过程时,回调的问题就开始了——这被称为回调地狱——这使得我们的代码很难阅读和维护。
JS 中的 Promise
ES2015 引入了 Promise,一种避免回调地狱的现代替代方案。
“Promise 对象表示异步操作的最终完成(或失败)及其结果值。” - MDN
简而言之,承诺充当未知值的代理,该值最终将在某个时刻变为可用,如果一切顺利,则最终处于解决状态,如果出现问题,则处于拒绝状态。
使用 Promise,我们调用它.then()
在结果被解决或被拒绝时执行.catch()
。此外,我们还可以链接 Promise,让一个 Promise 返回另一个 Promise。请看下面的示例:
let myPromise = new Promise(function(myResolve, myReject) {
// "Producing Code" (May take some time)
myResolve(); // when successful
myReject(); // when error
});
// "Consuming Code" (Must wait for a fulfilled Promise)
myPromise.then(
function(value) {
/* code if successful */
},
function(error) {
/* code if some error */
}
);
上面的例子来自 W3Schools。
JavaScript 中的 Fetch API 是什么以及如何使用它?
在解释 Fetch API 之前,我想先向你展示它的语法:
fetch('/https://api.github.com/users/dionarodrigues');
上面的代码只是向 GitHub API 域发出一个 HTTP 请求,以获取一些 JSON 数据。多么简洁明了的代码啊!
Fetch API 也是在 ES2015 中引入的,它是的现代继承者XMLHttpRequest
:该fetch()
方法将资源路径作为输入并返回一个 Promise,从而可以在解决或拒绝时执行函数。
fetch('https://api.github.com/users/dionarodrigues')
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.log(err));
在上面的例子中,您可以看到该fetch()
方法与 Fetch API 一起工作.then()
,并且.catch()
在后台使用 Promise:
- 向 GitHub API 域发出 HTTP 请求
- 如果已解析,则使用
.json()
方法将其转换为 JSON 数据 - As
.json()
方法返回另一个 Promise,如果已解决,则在控制台中显示结果。 - 如果上述任何步骤失败,请在控制台中显示错误
Async/Await 和 Fetch API
Async/Await 是在 ES2017 中引入的,作为 Promise 的语法糖,使得使用异步函数成为可能。
请参阅下面的代码及其描述,以更好地了解如何使用 Fetch API 实现 Async/Await:
async function getUserData() {
try {
const response = await fetch('https://api.github.com/users/dionarodrigues');
const data = await response.json();
console.log(data);
} catch (err) {
console.log(err);
}
}
上面的代码与上一段代码的工作方式相同。区别在于,我们不再需要使用 Promise 语法,而是使用包装器来重新定义 Promise,使其更易于阅读和使用。我们使用 关键字async
使此函数异步执行,并await
阻止异步函数内部代码的执行,直到进程终止。然后,我们使用try/catch
来处理已解决和已拒绝的状态。
将 try/catch 与异步函数一起使用的另一种方法是处理catch
函数外部 - 当它运行时:
async function getUserData() {
const response = await fetch('https://api.github.com/users/dionarodrigues')
const data = await response.json()
console.log(data)
}
getUserData.catch(err => console.log(err))
需要强调的是,这不会捕获诸如 404(未找到)或 500(内部服务器错误)之类的服务器错误,而只会捕获由网络或 CORS 问题引起的错误。想要了解更多关于如何使用 Fetch API 处理各种错误类型的信息,我推荐你阅读另一篇文章《Fetch API,你真的知道如何处理错误吗?》。
参考
- 维基百科上的 AJAX
- MDN 上的 XMLHttpRequest API
- Node.js 上的 JavaScript 异步编程和回调
- MDN 上的回调
- MDN 上的承诺
- 理解 Node.js 上的 JavaScript Promise
- 在 JavaScript.Info 上获取
- JavaScript.Info 上的 Async/await
结论
在 Web 发展的早期,AJAX 概念与 XMLHttpRequest API 一起被广泛使用。如今,我们通过使用 Fetch API,有了更好、更现代的异步数据处理方法。希望您理解了fetch()
本文中一些重要的 JavaScript 概念以及如何实现。如有任何问题,请随时提出,不要止步于此,请查看上面的参考资料,以便更好地理解。
下次再见。😁
文章来源:https://dev.to/dionarodrigues/fetch-api-is-new-old-version-of-ajax-1m14