当前位置:网站首页>【async/await】--异步编程最终解决方案
【async/await】--异步编程最终解决方案
2022-06-26 13:26:00 【codeMak1r.】
前言
欢迎来到我的博客
博主是一名大学在读本科生,主要学习方向是前端。
目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏🤩
目前正在学习的是 R e a c t 框 架 React框架 React框架,中间夹杂了一些基础知识的回顾️
博客主页codeMak1r.的博客
关注点赞收藏
坚持创作️,一起学习,码出未来!
async函数
async关键字用来标识一个函数,async关键字标识过的函数为async函数。
- 函数的返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
- async函数与promise.then()方法返回值情况类似
| async函数返回值 | async函数内部 |
|---|---|
| promise对象,对象的状态为成功,成功的值由async函数内部的返回值决定 | 一个非promise类型的返回值 |
| promise对象,状态为成功,成功的值为undefined。 | 没有声明return |
| promise对象,状态为成功,成功的值为123. | return 123; |
| promise对象,状态由返回值中的promise对象状态决定 对象的值由返回值中的promise对象的值决定 | 一个promise类型的返回值 |
| promise对象,状态为失败; 失败的值为‘error’。 | return Promise.reject(‘error’) |
| promise对象,状态为失败,失败的值为‘Oh NO!’ | throw ‘Oh NO!’ |
<body>
<script> async function main() {
return Promise.reject('error') } let result = main() console.log(result) </script>
</body>
打印台显示:
result是一个prmoise类型的对象,状态为失败,值为error。
<body>
<script> async function main() {
throw 'Oh NO!' } let result = main() console.log(result) </script>
</body>
打印台显示:
result是一个promise类型的对象,状态为失败,值为‘Oh NO!’。
await表达式
- await右侧的表达式一般为promise对象,但也可以是其他的值;
- 如果表达式是promise对象,await返回的是promise成功的值;
- 如果表达式是其他值,直接将此值作为await的返回值。
注意️:
- await必须写在async函数中,但async函数中可以没有await;
- 如果await 的promise失败了,就会抛出异常,需要通过try…catch捕获处理。
1、右侧为成功的promise
async function main() {
let p = new Promise((resolve, reject) => {
resolve('Ok')
})
let res = await p
console.log(res)
}
main()
打印台显示:
res结果为:Ok。
2、右侧不是promise类型的值
async function main() {
let p = new Promise((resolve, reject) => {
resolve('Ok')
})
let res = await 123
console.log(res)
}
main()
打印台显示:
res结果为:123。
3、右侧的promise是失败状态
async function main() {
let p = new Promise((resolve, reject) => {
reject('Error')
})
try {
let res = await p
} catch (error) {
console.log(error)
}
}
main()
打印台显示:
Error。
async_await结合使用——fs读取文件
普通回调函数读取文件操作:
const fs = require('fs');
fs.readFile('./resource/1.txt', (err, data1) => {
if (err) throw err;
fs.readFile('./resource/2.txt', (err, data2) => {
if (err) throw err;
console.log(data1 + data2)
})
})
我们可以看出,这一段代码运用了回调函数的嵌套,一旦读取的文件数量多的话就非常不利于阅读与维护。
于是可以使用promise异步编程解决方法:
const fs = require('fs');
// promise封装读取文件函数
const read = (path) => {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) reject(err);
resolve(data.toString())
})
})
}
// 使用promise.then()方法读取文件
read('./resource/1.txt').then(value => {
console.log(value)
return read('./resource/2.txt')
}).then(value => {
console.log(value)
}).catch(reason => {
console.warn(reason)
})
使用了promise之后,我们可以用then方法的链式调用,调用读取的文件并将读取结果打印出来。
但是依旧不够简洁,最终的解决方案是使用async_await结合:
const fs = require('fs');
// async与await方式实现
const util = require('util')
// util.promisify转为promise类型的函数
const mineReadFile = util.promisify(fs.readFile)
async function main() {
try {
// 读取文件内容
let data1 = await mineReadFile('./resource/1.txt')
let data2 = await mineReadFile('./resource/2.txt')
// 其实这里await读取文件依旧是异步的,只不过看上去像同步
console.log(data1 + data2)
} catch (error) {
console.log(error)
}
}
main();
util.promisify()方法将API转为promise类型的函数
这里的两行await代码看上去是同步代码,其实其内部依旧是异步读取文件,只不过看上去像是同步的。
async_await结合使用——发送ajax请求
promise.then.catch方法发送ajax请求:
<body>
<button id="btn">点击发送ajax请求</button>
<script>
function sendAJAX(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
}
const btn = document.getElementById('btn')
// promise.then.catch写法
btn.addEventListener('click', function () {
sendAJAX('http://127.0.0.1:8000/server')
.then(value => {
console.log(value)
})
.catch(reason => {
console.log(reason)
})
})
</script>
</body>
async_await写法发送ajax请求:
<body>
<button id="btn">点击发送ajax请求</button>
<script>
function sendAJAX(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
}
const btn = document.getElementById('btn')
// async_await写法
btn.addEventListener('click', async function () {
try {
let result = await sendAJAX('http://127.0.0.1:8000/server')
console.log(result)
} catch (error) {
console.log(error)
}
})
</script>
</body>
接收ajax请求的服务器:
server.js
const express = require('express')
const app = express()
app.all('/server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
response.setHeader('Access-Control-Allow-Methods', '*')
response.send('codeMak1r.')
})
app.listen(8000, () => {
console.log('服务已经监听到8000端口...')
})
如果觉得博主的文章还不错的话
关注博主点赞文章收藏文章
️原创不易你的支持将会是我最大的动力
🧸感谢观看
边栏推荐
- CF676C Vasya and String
- Why is there always a space (63 or 2048 sectors) in front of the first partition when partitioning a disk
- Knowledge about adsorption
- 2021-10-09
- Luogu p4145 seven minutes of God created questions 2 / Huashen travels around the world
- Sword finger offer 06.24.35 Linked list
- 虫子 STL string 下 练习题
- D check type is pointer
- C language | file operation and error prone points
- 9項規定6個嚴禁!教育部、應急管理部聯合印發《校外培訓機構消防安全管理九項規定》
猜你喜欢

windows版MySQL软件的安装与卸载

Jianzhi offer 43.47.46.48 dynamic planning (medium)

9 articles, 6 interdits! Le Ministère de l'éducation et le Ministère de la gestion des urgences publient et publient conjointement neuf règlements sur la gestion de la sécurité incendie dans les établ

Zero basics of C language lesson 8: Functions

How to call self written functions in MATLAB

Gartner 2022 Top Strategic Technology Trends Report

ICML 2022 | limo: a new method for rapid generation of targeted molecules

Generation and rendering of VTK cylinder

ICML 2022 | LIMO: 一种快速生成靶向分子的新方法

Wechat applet -picker component is repackaged and the disabled attribute is added -- below
随机推荐
Cloudcompare - Poisson reconstruction
GC is not used in D
数学建模经验分享:国赛美赛对比/选题参考/常用技巧
Luogu p4513 xiaobaiguang Park
Pointer
Wechat applet SetData dynamic variable value sorting
Difference between classification and regression
C | analysis of malloc implementation
Notes: the 11th and 12th generation mobile versions of Intel support the native thunderbolt4 interface, but the desktop version does not
Tips for using nexys A7 development board resources
证券开户安全吗,有没有什么危险啊
How to check if a text field is empty or not in swift
Sword finger offer 09.30 Stack
Jenkins build prompt error: eacces: permission denied
Assert and constd13
Sword finger offer 15.65.56 I 56Ⅱ. Bit operation (simple - medium)
Reprint - easy to use wechat applet UI component library
Zero basics of C language lesson 7: break & continue
Installation tutorial about origin2019
Use performance to see what the browser is doing