千家信息网

如何使用顶层await简化JS

发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,这篇文章将为大家详细讲解有关如何使用顶层await简化JS,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JavaScript 是一种流行的编程语言,最初被设计为单线
千家信息网最后更新 2024年11月29日如何使用顶层await简化JS

这篇文章将为大家详细讲解有关如何使用顶层await简化JS,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

JavaScript 是一种流行的编程语言,最初被设计为单线程和同步的语言,意味着程序需要在不等待获取外部资源或者耗时的计算的情况下一步一步的运行。如果脚本需要这样的资源或计算,这种同步行为将导致错误。这会阻塞队列中的所有其他进程运行,无论它们是否依赖于那些阻塞中的任务。

但很久以前,JavaScript 引入了一个机制让其可以在等待外部资源或者耗时任务的时候去执行其剩余的代码。这种异步行为是通过在函数上使用回调或 promise 来实现的。

什么是回调和promise

我将通过代码来解释这些概念。如果你已经知道回调和 promise 是什么,请直接跳到顶层 await 部分和示例应用程序。

回调

在回调中,一个函数作为参数传递给另一个函数;因此,下面 addEventListener 函数中的第二个参数是回调函数。此回调将等待第一个 click 事件发生,然后才执行第二个参数。

const x = document.getElementsByTagName('Button');  x[0].addEventListener('click',() =>{alert("I was clicked")})

这种等待行为使代码异步。这与同步代码不同,它可以接着一步一步的运行,而不需要等待资源下载或者耗时进程结束。但要注意,并非所有回调函数都是异步的。

Promises

Promises 类似于回调,它将函数附加到返回的对象上。但Promises和回调也有不同,Promises 是专门为异步方法设计的。它们只有一个参数和一个用来获得返回结果的 then() 函数。此外,它还可以链式的附加多个.then() 和 catch() 函数。

fetch('www.xyz.com/api')  .then((res)=>{let x = res.data; //do something with received data})  .catch((err)=>{console.log(err)})

Promises使用事件队列并严格遵循异步任务被链接的顺序来执行。

Async/await

Async/await 是对 Promises 的语法改进,以避免链式调用。它能使代码更清晰,更容易理解。await 关键字使代码暂停,直到 Promises 成功(resolved)或者失败(resolved)。

async function asyncwaitcode(){    let getData = await axios('www.xyzdata.org/api')    console.log(getData.data)  }

什么是顶层 await

以上所有示例都让功能块中的代码异步,没有一个在模块级工作。

但是,异步行为是可以在模块级别实现的。使用顶级 await 的模块会在异步初始化其命名空间后,再通知该模块的消费者继续执行它自己的代码。

下面的示例代码展示了如何使用顶级 await。

关于App

此应用将从新闻 API 中获取最热门的新闻数据,并在浏览器中呈现。用户还能以相关搜索词的进行新闻数据搜索。在开始之前,有几点需要注意:

  • 顶级await在node 13.3及更高版中被支持

  • 顶级await只在ECMAScript模块中支持,但Node.js和Express都是CmmonJS模块。CmmonJS不支持顶级await特性。所以我在代码中会使用import而不是require

  • 在node 14.x之前,顶级await不能直接使用,需要启用--harmony

  • 循环引用模块可能会导致死锁

构建App

1. 创建toplevelawait目录

$ mkdir toplevelawait

2. npm init初始化

$ npm init

3.package.json中增加"type": "module",以支持ECMAScript模块

"author": "",  "license": "ISC",  "type": "module",

4.在toplevelawait目录下创建src目录。注意使用mjs作为文件后缀名。

$ touch app.mjs  $ touch exp.mjs  $ ls -1 src  app.mjs exp.mjs

5. 安装依赖axios, ejs和 express

$ npm install axios ejs express --save

6. exp.mjs中增加下面代码:

import express from "express"  export const exp = await express();

注意我们是在没有async的情况下使用await。这样express实例会先初始化后再导出給其他模块。你可以用这种方式等待模块中某个实例初始化后完成后,再执行依赖于该模块的代码。

如果一个模块包含了顶层await,那么它的父模块的执行会停止,直到promise完成。但他的兄弟模块会继续执行,和以前的同步模式相同。

要注意Node.js中的模块加载也是同步的,意味着他不能异步的等待资源加载。但你可以在加载或者处理资源的语句前加上await关键字来实现异步等待。

增加news APIs

这个应用使用两个免费的新闻API来获取数据。两个API支持回退依赖行为;如果一个API失败,另一个API将获取数据。这两个API都使用API密钥:

  • News API[1]

  • GNews API[2]

在app.mjs文件中插入下面的代码。前面的目标导入axios和在exp.js被初始化的express实例。下一部分设置视图引擎,以便在浏览器中展示。

import { exp } from "./exp.mjs";  import axios from "axios"  exp.set("view engine","ejs");  // dependency fall back  let response = "";  let site = true;  try{     response = await axios('https://newsapi.org/v2/top-headlines?country=us&apiKey=your-api-key');     }   catch{    response = await axios("https://gnews.io/api/v3/top-news?token=your-api-key");    site = false;   }   // Get top news  exp.get('/',function(req,res){    let responseresponse0 = response.data.articles      res.render('main.ejs',{response0: response0, site:site})   })   // search news  exp.get('/search', function(req,res){    res.render("searchnews.ejs")    })  exp.get('/result', async(req, res)=>{    let x = req.query.newtitlesearch;    let response1 = {}    let data = {}    try{      let url = 'https://newsapi.org/v2/everything?q='+x+'&apiKey=your-api-key'      response1 =  await axios(url);   }    catch{      let url = 'https://gnews.io/api/v3/search?q='+x+'&token=your-api-key'      response1 =  await axios(url)    }    res.render('result.ejs', {response1: response1.data.articles, site: site})    })  exp.listen(3000)

最重要的部分是这个try catch块,使用到了顶层await来等待axios去获取数据。如果由于任何原因,axios无法从第一个API获取数据,应用将使用第二个API获取数据。一旦它从API获得数据,express可以在主页上呈现它。

try{     response = await axios('https://newsapi.org/v2/top-headlines?country=us&apiKey=your-api-key');    }   catch{    response = await axios("https://gnews.io/api/v3/top-news?token=your-api-key");    }

接下来提供了一个可以让用户进行搜索的路由:

// search news  exp.get('/search', function(req,res){    res.render("../src/view/searchnews.ejs")  })

最后,另一个路径展示搜索结果:

exp.get('/result', async(req,res)=>{    let x = req.query.newtitlesearch;    let response1 = {}    let data = {}    try{      let url = 'https://newsapi.org/v2/everything?q='+x+'&apiKey=your-api-key'     response1 =  await axios(url);    }    catch{      let url = 'https://gnews.io/api/v3/search?q='+x+'&token=your-api-key'      response1 =  await axios(url)    }    res.render('../src/view/result.ejs', {response1: response1.data.articles , site: site})    })

写前端界面

应用的最后一部分是为前端页面编写四个.ejs HTML文件。将这些文件保存在"view"文件夹中:

//header.ejs          newapiapp              
//main.ejs  <%include('header');%>  <%let rows = response0%>  <%let sitesiterep = site%>  
<% for(let i = 0; i < rows.length; i++){%>
<%= rows[i].title%>
<% } %>
//searchnews.ejs  <%- include('header');%>    

Search news

//result.ejs  <%- include('header');%>  <%let rows = response1%>  <%let sitesiterep = site%>  
<% for(let i = 0; i < rows.length; i++){%>
<%= rows[i].title%>
<% } %>

运行app

现在APP已经完成,你可以尝试下。

如果你在使用node.js v13.3 至 v14.0,运行:

$ node --harmony-top-level-await app.js

如果你在使用node.js v14.0以上,你不需要--harmony flag:

$ node app.js

如果你成功构建了这个app,那么恭喜你又学会了一个新的js特性。

关于"如何使用顶层await简化JS"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

模块 代码 函数 数据 资源 顶级 顶层 文件 行为 同步 应用 支持 运行 参数 新闻 搜索 两个 任务 实例 目录 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 聊城市中等职业学校有软件开发吗 为什么酷酷跑连接服务器失败 计算机网络技术专业学历要求 安卓手机如何导入db数据库 昆明取消网络安全许可证 网络安全周信息意识漫谈 在数据库如何查出姓李的老师 如何设置邮箱服务器不保留邮件 长江存储服务器芯片 软件开发 类excel界面 表格怎样导入导出数据库 福建个人软件开发供应 新科技与互联网保险 2003 dhcp服务器 江苏售后备件管理软件开发 上海奥邦网络技术有限公司 学校冬奥会冬残奥会网络安全保障工作总结 北京做网络安全电话 数据库原理及应用第2版实验 网络安全测评试题 湖北的软件开发 网络技术创新项目 服务器通电后开机没任何反应 哪些企业租用阿里云服务器 批量更新数据库语句 计算机软件开发培训 嘉兴电话视频系统服务器 孙吴网络安全宣传 软件开发大概一年收入多少 直销专业软件开发公司
0