疯狂的技术宅

以前出于工作目的,编写和翻译了大量的技术文章,以前端为主,删掉了过时的、毫无营养的内容,留下的都是精华。


  • 首页

  • 分类

  • 标签

  • 归档

  • 关于本站

  • 回到主站

  • 搜索

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

时间: 2021-06-14 分类: 前端技术   字数: 1075 字 阅读: 3分钟
标签: #JavaScript# #Promise# #Async/Await# #案例#

本文将通过代码示例展示如何使用基于回调的 API,然后将其改成使用 Promises,最后再用 Async/Await 语法。本文不会详细解释回调、promise 和 Async/Await 语法。 有关这些概念的详细解释,请查看 MDN 的 Asynchronous JavaScript ,它解释了 异步性 以及如何用回调、promise 和 Async/Await 语法处理异步 JavaScript。

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

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

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

废话少说,开始!

使用回调

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

先创建着两个文件;

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

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

const fs = require("fs")

function readFileCallBack() {

fs.readFile("./test.txt", 'utf8',  (err, data) => {
  if (err) {
    console.error(err)
    return
  }
  
  console.log(data.trim() + " [callback]")
 })

}

readFileCallBack()

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

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

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

使用 Promise

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

function readFilePromise() {
  return new Promise((resolve, reject) => {
     fs.readFile("./test.txt", 'utf8',  (err, data) => {
     if (err) {
       reject(err)
       return
     }

      resolve(data.trim())
    })
  });
}


readFilePromise()
 .then(data => console.log(data  + " [promise]"))
 .catch(err => console.log(err))

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

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

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

使用 Async/Await

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

async function readFileAsync() {
  try {
    const data = await readFilePromise()
    console.log(data.trim() + " [async-await]")
  } catch (err) {
    console.log(err)
  }
}

readFileAsync()

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

Beam me up, Scotty [callback]
Beam me up, Scotty [promise]
Beam me up, Scotty [async-await]

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

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

const fs = require("fs")

// callback
function readFileCallBack() {

fs.readFile("./test.txt", 'utf8',  (err, data) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(data.trim() + " [callback]")
  
 })

}

readFileCallBack()

// promise
function readFilePromise() {
  return new Promise((resolve, reject) => {
     fs.readFile("./test.txt", 'utf8',  (err, data) => {
     if (err) {
       reject(err)
       return
     }

      resolve(data.trim())
    })
  });
}


readFilePromise()
 .then(data => console.log(data  + " [promise]"))
 .catch(err => console.log(err))


// async/await
async function readFileAsync() {
  try {
    const data = await readFilePromise()
    console.log(data.trim() + " [async-await]")
  } catch (err) {
    console.log(err)
  }
}

readFileAsync()

错误处理

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

$ mv test.txt test.txt.backup
$ node script.js
[Error: ENOENT: no such file or directory, open './test.txt'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: './test.txt'
}
[Error: ENOENT: no such file or directory, open './test.txt'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: './test.txt'
}
[Error: ENOENT: no such file or directory, open './test.txt'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: './test.txt'
}

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

标签: #JavaScript# #Promise# #Async/Await# #案例#

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

链接:https://fe-tech.viewnode.com/post/202106/14/

作者:疯狂的技术宅

声明: 本博客文章除特别声明外,均采用 CC BY-NC-ND 4.0 国际许可协议( 知识共享署名-非商业性使用-禁止演绎 4.0),转载请注明出处!

6个好用的 vue 内容加载动画库
7个使 vue 开发如虎添翼的VS Code 扩展
  • 文章目录
  • 站点概览
疯狂的技术宅

疯狂的技术宅

退休程序员,硬件发烧友,人工智能爱好者。写写代码喝喝茶,晒晒太阳带带娃。

457 日志
8 分类
583 标签
GitHub
友情链接
  • viewnode
  • mofish
标签云
  • Javascript 172
  • Node.Js 62
  • Vue 36
  • Typescript 28
  • 实战项目 28
  • 面试 21
  • React 20
  • Css 17
  • 面试题 16
  • 教程 13
  • Promise 12
  • Chrome 9
  • Debug 9
  • 调试 9
  • 资源 9
  • Deno 8
  • Dom 8
  • 杂谈 8
  • 正则表达式 8
  • 测试 8
    • 使用回调
    • 使用 Promise
    • 使用 Async/Await
    • 错误处理
© 2018 - 2022 疯狂的技术宅 All Rights Reserved
Powered by - Hugo v0.99.0 / Theme by - NexT
Storage by 俺的服务器 / 冀ICP备2022010157号
0%