async/await 异步操作

核心作用是让异步代码写起来像同步代码一样简洁、易读。它的使用场景本质上和需要等待某个操作完成后再执行后续逻辑的场景一致,要遇到耗时且不阻塞主线程操作,用 async/await 能大幅提升代码可读性和可维护性。

例子:网络请求

任何需要向服务器发送请求获取数据、提交数据的场景,都是 async/await 的核心使用场景。因为网络请求是耗时操作,且 JavaScript 是单线程的,必须使用异步处理,否则会阻塞页面。

接口请求数据

异步示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 封装请求函数,返回Promise
function fetchUserInfo(userId) {
return fetch(`/api/user/${userId}`)
.then(res => res.json());
}
async function getUserData() {
try {
const userInfo = await fetchUserInfo(123); ​
console.log("用户信息:", userInfo);
renderUser(userInfo); // 渲染用户信息到页面​
} catch (error) {
console.error("请求失败:", error);​
showErrorMsg("获取用户信息失败,请重试");​
}
}​

getUserData();

Promise写法

1
2
3
4
5
6
7
8
9
fetchUserInfo(123)
.then(userInfo => {
console.log("用户信息:", userInfo);
renderUser(userInfo);
})
.catch(error => {
console.error("请求失败:", error);
showErrorMsg("获取用户信息失败,请重试");
});

当有多个依赖请求时,如先获取用户 ID,再用 ID 获取详情,async/await 的优势更明显:

1
2
3
4
5
6
7
8
9
10
async function getFullUserData() {
try {
const userId = await fetchUserId(); //获取用户 ID
const userInfo = await fetchUserInfo(userId); //用 ID 获取详情,依赖第一步结果
const userOrders = await fetchUserOrders(userId); //第三步:获取用户订单
console.log("完整数据:", { userInfo, userOrders });
} catch (error) {
console.error("失败:", error);
}
}

什么时候不适合用

简单的同步操作
无依赖的简单异步操作,如果只是单纯执行一个异步操作,不需要等待结果,也不需要后续逻辑,直接用 Promise 或回调即可,比如简单的日志上报。
需要极致性能优化的时候,async/await 比原生 Promise 多一层封装,性能损耗极小,几乎可忽略,但如果是对性能要求极高的底层库,可考虑直接用 Promise。

总结来说是

所有需要等待某个异步操作完成后再执行后续逻辑的场景
网络请求
数据库操作
文件I/O
延迟操作/定时器
复杂依赖的异步流程

express框架

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助创建各种 Web 应用和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。

  • 可以设置中间件来响应 HTTP 请求
  • 定义了路由表用于执行不同的 HTTP 请求动作
  • 可以通过向模板传递参数来动态渲染 HTML 页面

使用 Express 框架来输出 “Hello World”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let express = require('express');
let app = express();

app.get('/', function (req, res) {
res.send('<h1>Hello World</h1>');
})
app.get('/about', function (req, res) {
res.send("This is about page")
})
let server = app.listen(7070, function () {
let host = server.address().address
let port = server.address().port
console.log("实例访问地址 http://%s:%s", host, port)

})

执行上述代码
执行结果
Express 使用回调函数的参数request 和 response 来处理请求和响应数据

1
2
3
app.get('/', function (request, response) {
// 其他代码……
})

请求 & 响应

Request

表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性

  • request.app:当callback为外部文件时,用request.app访问express的实例
  • request.baseUrl:获取路由当前安装的URL路径
  • request.body / request.cookies:获得请求主体/ Cookies
  • request.fresh / request.stale:判断请求是否新鲜
  • request.hostname / request.ip:获取主机名和IP地址
  • request.originalUrl:获取原始请求URL
  • request.params:获取路由的parameters
  • request.path:获取请求路径
  • request.protocol:获取协议类型
  • request.query:获取URL的查询参数串
  • request.route:获取当前匹配的路由
  • request.subdomains:获取子域名
  • request.accepts():检查可接受的请求的文档类型
  • request.acceptsCharsets / request.acceptsEncodings / request.acceptsLanguages:返回指定字符集的第一个可接受字符编码
  • request.get():获取指定的HTTP请求头
  • request.is():判断请求头Content-Type的MIME类型

Response

表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据

  • response.app:同request.app一样
  • response.append():追加指定HTTP头
  • response.set()在response.append()后将重置之前设置的头
  • response.cookie(name,value [,option]):设置Cookie,opition: domain / expires / httpOnly / maxAge / path / secure / signed
  • response.clearCookie():清除Cookie
  • response.download():传送指定路径的文件
  • response.get():返回指定的HTTP头
  • response.json():传送JSON响应
  • response.jsonp():传送JSONP响应
  • response.location():只设置响应的Location HTTP头,不设置状态码或者close response
  • response.redirect():设置响应的Location HTTP头,并且设置状态码302
  • response.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
  • response.send():传送HTTP响应
  • response.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
  • response.set():设置HTTP头,传入object可以一次设置多个头
  • response.status():设置HTTP状态码
  • response.type():设置Content-Type的MIME类型

路由

路由决定了由谁去响应客户端请求。
在HTTP请求中,可以通过路由提取出请求的URL以及GET/POST参数。
扩展 Hello World,添加一些功能来处理更多类型的 HTTP 请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var express = require('express');
var app = express();
app.get('/', function (req, res) {
console.log(" GET 请求");
res.send('Hello GET');
})

app.post('/', function (req, res) {
console.log("POST 请求");
res.send('Hello POST');
})
app.get('/about', function (req, res) {
console.log("about 关于页面");
res.send('关于页面');
})
app.get('/ab*cd', function(req, res) {
console.log("/ab*cd GET 请求");
res.send('正则匹配');
})


var server = app.listen(8081, function () {

var host = server.address().address
var port = server.address().port

console.log("实例访问地址 http://%s:%s", host, port)

})