文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript 中回调、Promise 和 Async/Await 的代码案例

2024-12-03 04:15

关注

如果你对 JavaScript 中的异步有一定的了解,但需要一个直观的代码案例作为参考,那么本文就是给你准备的。

出于演示目的,我们将使用 fs.readFile[2],这是一个基于回调的用于读取文件的 API。我们将会先创建一个包含一些文本的文件 test.txt,然后用 script.js 来打开文件、读取内容并将其输出到终端。

代码将首先用回调实现,然后将其修改为使用 Promise,最后改为使用 Async/Await,而不是直接使用 Promise。

废话少说,开始!

使用回调

首先创建一个目录,里面包含我们的代码文件和要进行读取操作的文件。

先创建着两个文件;

  1. $ mkdir ~/code 
  2. $ touch ~/code/script.js 
  3. $ echo "Beam me up, Scotty" > ~/code/test.txt 
  4. $ cd ~/code/ 

在 script.js 文件中,输入以下代码:

  1. const fs = require("fs") 
  2.  
  3. function readFileCallBack() { 
  4.  
  5. fs.readFile("./test.txt", 'utf8',  (err, data) => { 
  6.   if (err) { 
  7.     console.error(err) 
  8.     return 
  9.   } 
  10.    
  11.   console.log(data.trim() + " [callback]") 
  12.  }) 
  13.  
  14.  
  15. readFileCallBack() 

通过 node script.js 命令执行脚本,会在终端上输出“Beam me up, Scotty”:

  1. $ node script.js 
  2. Beam me up, Scotty [callback] 

对于回调的写法,异步操作的结果会被传给执行异步操作的函数,并由其进行处理。

使用 Promise

修改 script.js 并添加一个使用 promise 的 readFileCallback 版本。代码如下:

  1. function readFilePromise() { 
  2.   return new Promise((resolve, reject) => { 
  3.      fs.readFile("./test.txt", 'utf8',  (err, data) => { 
  4.      if (err) { 
  5.        reject(err) 
  6.        return 
  7.      } 
  8.  
  9.       resolve(data.trim()) 
  10.     }) 
  11.   }); 
  12.  
  13.  
  14. readFilePromise() 
  15.  .then(data => console.log(data  + " [promise]")) 
  16.  .catch(err => console.log(err)) 

通过 node script.js 命令来执行脚本:

  1. $ node script.js 
  2. Beam me up, Scotty [callback] 
  3. Beam me up, Scotty [promise] 

使用promise,异步操作的结果由传递给 promise 对象公开的 then 函数进行处理。

使用 Async/Await

修改 script.js 并添加使用 Async/Await 语法的第三个版本。由于 Async/Await 是一种能让 promise 更容易的语法,所以 Async/Await 实现将使用 readFilePromise() 函数。代码是这样的:

  1. async function readFileAsync() { 
  2.   try { 
  3.     const data = await readFilePromise() 
  4.     console.log(data.trim() + " [async-await]") 
  5.   } catch (err) { 
  6.     console.log(err) 
  7.   } 
  8.  
  9. readFileAsync() 

Executing the script by running node script.js will print something similar to this, to the terminal: 通过运行节点脚本执行脚本.js将打印与此类似的东西,到终端:

  1. Beam me up, Scotty [callback] 
  2. Beam me up, Scotty [promise] 
  3. Beam me up, Scotty [async-await] 

使用 async/await,异步操作的结果被当作同步操作来处理。await 对此负责,而使用它的函数必须以 async 关键字开头。

3种实现的完整代码如下:

  1. const fs = require("fs") 
  2.  
  3. // callback 
  4. function readFileCallBack() { 
  5.  
  6. fs.readFile("./test.txt", 'utf8',  (err, data) => { 
  7.   if (err) { 
  8.     console.error(err) 
  9.     return 
  10.   } 
  11.   console.log(data.trim() + " [callback]") 
  12.    
  13.  }) 
  14.  
  15.  
  16. readFileCallBack() 
  17.  
  18. // promise 
  19. function readFilePromise() { 
  20.   return new Promise((resolve, reject) => { 
  21.      fs.readFile("./test.txt", 'utf8',  (err, data) => { 
  22.      if (err) { 
  23.        reject(err) 
  24.        return 
  25.      } 
  26.  
  27.       resolve(data.trim()) 
  28.     }) 
  29.   }); 
  30.  
  31.  
  32. readFilePromise() 
  33.  .then(data => console.log(data  + " [promise]")) 
  34.  .catch(err => console.log(err)) 
  35.  
  36.  
  37. // async/await 
  38. async function readFileAsync() { 
  39.   try { 
  40.     const data = await readFilePromise() 
  41.     console.log(data.trim() + " [async-await]") 
  42.   } catch (err) { 
  43.     console.log(err) 
  44.   } 
  45.  
  46. readFileAsync() 

错误处理

为了验证在 3 种代码实现在工作时错误处理是否会按预期工作,重命名 test.txt 文件并重新运行脚本:

  1. $ mv test.txt test.txt.backup 
  2. $ node script.js 
  3. [Error: ENOENT: no such file or directory, open './test.txt'] { 
  4.   errno: -2, 
  5.   code: 'ENOENT', 
  6.   syscall: 'open', 
  7.   path: './test.txt' 
  8. [Error: ENOENT: no such file or directory, open './test.txt'] { 
  9.   errno: -2, 
  10.   code: 'ENOENT', 
  11.   syscall: 'open', 
  12.   path: './test.txt' 
  13. [Error: ENOENT: no such file or directory, open './test.txt'] { 
  14.   errno: -2, 
  15.   code: 'ENOENT', 
  16.   syscall: 'open', 
  17.   path: './test.txt' 

3种实现都会显示错误处理代码(仅将错误输出到控制台),说明它们都按预期执行了。

 

来源:前端先锋内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯