JavaScript-中的异步操作

Promise

Promise 是 JavaScript 中用于处理异步操作的一种对象, 它代表一个未来可能完成的操作及其结果 (或失败的原因).

Promise 的状态

一个 Promise 对象有以下三种状态:

  1. Pending (进行中): 初始状态, 既不是成功也不是失败
  2. Fulfilled (已成功): 操作成功完成
  3. Rejected (已失败): 操作失败

Promise 的基本使用

创建一个 Promise

1
2
3
4
5
6
7
8
9
10
11
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true; // 假设这是异步操作的结果
if (success) {
resolve("success");
} else {
reject(new Error('fail'));
}
}, 1000);
});

创建 Promise 对象时, 会自动传入两个回调函数:

  • resolve: 将 Promise 的状态从 pending 变为 fulfilled, 其参数为成功的结果
  • reject: 将 Promise 的状态从 pending 变为 rejected, 其参数指定失败的结果

处理 Promise

使用 then 方法处理成功的结果, 使用 catch 方法处理失败的结果:

1
2
3
4
5
6
7
promise
.then(result => {
console.log(result); // 操作成功
})
.catch(error => {
console.error(error); // 操作失败
});

这里的 result 其实就是 resolve 传递的值; 同理, errorreject 传递的值.

async/await 关键字

async 用于定义一个异步函数, 其默认返回一个 Promise 对象.

await 关键字只能在 async 函数内部使用. 它用于等待一个 Promise 对象的 resolv 或 reject. 在 await 表达式右侧的 Promise 对象 resolve 时, await 表达式会返回 Promise resolve 时的值; 如果 Promise 被 reject, await 表达式会抛出一个错误.

示例

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { useState } from 'react';

export default function Form() {
const [answer, setAnswer] = useState('');
const [error, setError] = useState(null);
const [status, setStatus] = useState('typing');

if (status === 'success') {
return <h1>答对了!</h1>
}

async function handleSubmit(e) {
e.preventDefault();
setStatus('submitting');
try {
await submitForm(answer);
setStatus('success');
} catch (err) {
setStatus('typing');
setError(err);
}
}

function handleTextareaChange(e) {
setAnswer(e.target.value);
}

return (
<>
<h2>城市测验</h2>
<p>
哪个城市有把空气变成饮用水的广告牌?
</p>
<form onSubmit={handleSubmit}>
<textarea
value={answer}
onChange={handleTextareaChange}
disabled={status === 'submitting'}
/>
<br />
<button disabled={
answer.length === 0 ||
status === 'submitting'
}>
提交
</button>
{error !== null &&
<p className="Error">
{error.message}
</p>
}
</form>
</>
);
}

function submitForm(answer) {
// 模拟接口请求
return new Promise((resolve, reject) => {
setTimeout(() => {
let shouldError = answer.toLowerCase() !== 'lima'
if (shouldError) {
reject(new Error('猜的不错,但答案不对。再试试看吧!'));
} else {
resolve();
}
}, 1500);
});
}

JavaScript-中的异步操作
http://example.com/2024/07/17/JavaScript-中的异步操作/
作者
Jie
发布于
2024年7月17日
许可协议