首页 > web前端 > js教程 > 使用FETCH API和ES6发电机的异步API

使用FETCH API和ES6发电机的异步API

William Shakespeare
发布: 2025-02-19 08:43:09
原创
817 人浏览过

Asynchronous APIs Using the Fetch API and ES6 Generators

核心要点

  • ECMAScript 6 (ES6) 通过 Promise 和 Generator 更好地支持异步编程,并引入了 Fetch API,旨在取代 XMLHttpRequest 成为与远程资源通信的基础。
  • Fetch API 的方法返回 ES6 Promise 对象,这些对象可以与 Generator 一起使用,构成复杂异步操作的基础,例如一系列操作,其中每个操作都依赖于前一个操作返回的值。
  • Generator 可以与 Fetch API 一起用于执行诸如长轮询之类的任务,其中客户端不断向服务器发送请求,直到获得响应。这是通过在响应包含数据之前产出响应来完成的。
  • Fetch API 和 ES6 Generator 还可以用于实现多个依赖的异步调用,其中每个后续操作都依赖于前一个操作返回的值。这可以通过将它们放在一个 Generator 函数中并在需要时执行它来完成。

ECMAScript 6(又名 ECMAScript 2015 或 ES6)为 JavaScript 带来了许多新特性,使其成为大型应用程序的理想选择。其中一项特性是使用 Promise 和 Generator 更好地支持异步编程。另一项是增加了 Fetch API,旨在取代 XMLHttpRequest 成为与远程资源通信的基础。

Fetch API 的方法返回 ES6 Promise 对象,这些对象可以与 Generator 结合使用,构成复杂异步操作的基础。这可以是任何东西,从一系列异步操作(其中每个操作都依赖于前一个操作返回的值)到必须重复向服务器发出异步调用以获取最新更新的操作。

在本文中,我们将了解如何将 Fetch API 与 Generator 结合使用来构建异步 API。Fetch API 目前受 Chrome、Opera、Firefox 和 Android 浏览器支持。对于不受支持的浏览器,我们提供了一个来自 GitHub 的 polyfill。

与往常一样,本文的代码可以在我们的 GitHub 存储库中找到,文章底部有一个最终技术的演示。

使用 Generator 进行异步操作

提示:如果您需要复习 Generator 的内容及其工作方式,请查看:ECMAScript 2015:Generator 和迭代器

那么,我们如何使用 Generator 执行异步操作呢?好吧,如果我们分析 Generator 的工作方式,我们就会找到答案。

实现迭代器的 Generator 函数具有以下结构:

function *myIterator(){
  while(condition){
    //计算要返回的下一个值
    yield value;
  }
}
登录后复制
登录后复制
登录后复制

yield 关键字负责返回结果并暂停迭代器函数的执行,直到下次调用它为止。它还保留函数的状态,而不是在下次调用时重新运行所有内容,有效地记住它上次离开的地方。

我们可以将上述函数重新设想为没有 while 循环的形式:

function *myIterator(){
  while(condition){
    //计算要返回的下一个值
    yield value;
  }
}
登录后复制
登录后复制
登录后复制

在上述两种情况下,函数的行为是相同的。使用 yield 关键字的唯一原因是暂停函数的执行,直到下一次迭代(这本身似乎有点异步)。由于 yield 语句可以返回任何值,我们也可以返回 Promise 并使函数运行多个异步调用。

将 Generator 与 Fetch API 结合使用

提示:有关 Fetch API 的复习,请查看:Fetch API 简介

如前所述,Fetch API 旨在取代 XMLHttpRequest。这个新的 API 提供了对 HTTP 请求各个部分的控制,并返回一个 Promise,该 Promise 根据服务器的响应而解析或拒绝。

长轮询

Fetch API 和 Generator 可以一起使用的用例之一是长轮询。长轮询是一种技术,其中客户端不断向服务器发送请求,直到获得响应。在这种情况下,可以使用 Generator 不断产出响应,直到响应包含数据为止。

为了模拟长轮询,我在示例代码中包含了一个 Express REST API,该 API 在五次尝试后响应城市的实时天气信息。以下是 REST API:

function *myIterator(){
  //计算值 1
  yield value1;

  //计算值 2
  yield value2;
  ...

  //计算值 n
  yield valuen;
}
登录后复制
登录后复制

现在,让我们编写一个 Generator 函数,该函数多次调用此 API 并在每次迭代时返回一个 Promise。在客户端,我们不知道在多少次迭代后我们将从服务器获取数据。因此,此方法将具有一个无限循环,每次迭代都会 ping 服务器并在每次迭代时返回 Promise。以下是此方法的实现:

var polls=0;

app.get('/api/currentWeather', function(request, response){
  console.log(polls, polls < 5);
  if(polls < 5){
    polls++;
    response.send({});
  } else {
    response.send({temperature: 25});
  }
});
登录后复制
登录后复制

我们需要一个函数来不断调用此函数并检查 Promise 解析后值是否存在。它将是一个递归函数,调用 Generator 的下一次迭代,并且只有在找到从 Generator 返回的值时才会停止该过程。以下代码片段显示了此方法的实现以及调用此方法的语句:

function *pollForWeatherInfo(){
  while(true){
    yield fetch('/api/currentWeather',{
      method: 'get'
    }).then(function(d){
      var json = d.json();
      return json;
    });
  }
}
登录后复制

正如我们在这里看到的,对函数 runPolling 的第一次调用创建了 Generator 对象。next 方法返回一个带有 value 属性的对象,在我们的例子中,它包含 fetch 方法返回的 Promise。当此 Promise 解析时,它将包含一个空对象(如果 polls 变量小于 5 则返回),或包含所需信息的另一个对象。

接下来,我们检查此对象的 temperature 属性(这将表示成功)。如果它不存在,我们将 Generator 对象传递回下一个函数调用(以免丢失 Generator 的状态),或者我们将对象的值打印到控制台。

要查看它的实际效果,请从我们的存储库中获取代码,安装依赖项,启动服务器,然后导航到 https://www.php.cn/link/494ad0d24e15c7da81c7ea265c7f4cb4 shell 中看到以下结果:

0 true sending...empty 1 true sending...empty 2 true sending...empty 3 true sending...empty 4 true sending...empty 5 false sending...object

以及打印到浏览器控制台的对象本身。

多个依赖的异步调用

通常,我们需要实现多个依赖的异步调用,其中每个后续异步操作都依赖于前一个异步操作返回的值。如果我们有一组这样的操作并且它们必须多次调用,我们可以将它们放在一个 Generator 函数中并在需要时执行它。

为了演示这一点,我将使用 GitHub 的 API。此 API 使我们可以访问有关用户、组织和存储库的基本信息。我们将使用此 API 获取对组织的随机存储库的贡献者列表并在屏幕上显示获取的数据。

为此,我们需要调用三个不同的端点。以下是需要执行的任务:

  • 获取组织的详细信息
  • 如果组织存在,则获取组织的存储库
  • 获取其中一个组织存储库(随机选择)的贡献者

让我们创建一个围绕 Fetch API 的包装函数,以避免重复编写代码来创建标头和构建请求对象。

function *myIterator(){
  while(condition){
    //计算要返回的下一个值
    yield value;
  }
}
登录后复制
登录后复制
登录后复制

以下函数使用上述函数并在每次调用时产生一个 Promise:

function *myIterator(){
  //计算值 1
  yield value1;

  //计算值 2
  yield value2;
  ...

  //计算值 n
  yield valuen;
}
登录后复制
登录后复制

现在,让我们编写一段逻辑来调用上述函数以获取 Generator,然后使用从服务器获得的值来填充 UI。由于对 Generator 的 next 方法的每次调用都会返回一个 Promise,我们将不得不链接这些 Promise。以下是使用上述函数返回的 Generator 的代码框架:

var polls=0;

app.get('/api/currentWeather', function(request, response){
  console.log(polls, polls < 5);
  if(polls < 5){
    polls++;
    response.send({});
  } else {
    response.send({temperature: 25});
  }
});
登录后复制
登录后复制

(此处省略了Demo部分,因为无法在Markdown中呈现CodePen)

结论

在本文中,我演示了如何将 Fetch API 与 Generator 结合使用来构建异步 API。ECMAScript 6 将为该语言带来大量新特性,寻找创造性的方法来组合它们并利用它们的力量通常会带来出色的结果。但你怎么看?这是我们可以立即在我们的应用程序中开始使用的一种技术吗?我很想在评论中听到您的想法。

(此处省略了FAQ部分,因为内容与前面已有的信息高度重复)

以上是使用FETCH API和ES6发电机的异步API的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板