鸿蒙-Promise 并发(JS)

Promise 并发(JS)

在 async 函数中,“过度 await”代码非常普遍。将 Promise.all() 与异步函数一起使用,可以有效的实现并发。

例如,两个异步函数 fetchA, fetchB:

1
2
3
4
5
6
7
8
9
async function fetchA() {
const response = await fetch("/path/a");
return await response.json();
}

async function fetchB() {
const response = await fetch("/path/b");
return await response.json();
}

await 运算符会让异步函数串行执行,执行 fetchA()获得结果之后,才去执行 fetchB()。如下:

1
2
3
4
5
async function awaitFunc() {
const a = await fetchA();
const b = await fetchB();
return handleResult(a, b);
}

我们可以使用 Promise.all 让异步函数并发执行。

1
2
3
4
async function promiseAllFunc() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
return handleResult(a, b);
}

Promise 类提供了以下四种异步任务的并发。

Ox01 Promise.all()

Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。

  • 所有的 Promise 都被兑现时兑现,并返回一个包含所有兑现值的数组;
  • 在任何一个输入的 Promise 被拒绝时立即拒绝,并带回被拒绝的原因;
1
2
3
4
5
6
7
8
9
10
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});

Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// Expected output: Array [3, 42, "foo"]

Ox02 Promise.allSettled()

Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

  • 在所有的 Promise 都被敲定时兑现,返回一个带有描述每个 Promise 结果的对象数组;
  • 永远不会被 reject;
1
2
3
4
5
6
7
8
9
10
11
12
13
Promise.allSettled([
Promise.resolve(33),
new Promise((resolve) => setTimeout(() => resolve(66), 0)),
99,
Promise.reject(new Error("一个错误")),
]).then((values) => console.log(values));

// [
// { status: 'fulfilled', value: 33 },
// { status: 'fulfilled', value: 66 },
// { status: 'fulfilled', value: 99 },
// { status: 'rejected', reason: Error: 一个错误 }
// ]
  • status: 一个字符串,要么是 “fulfilled”,要么是 “rejected”,表示 promise 的最终状态。
  • value: 仅当 status 为 “fulfilled”,才存在。promise 兑现的值。
  • reason: 仅当 status 为 “rejected”,才存在,promsie 拒绝的原因。

Ox03 Promise.any()

在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。

1
2
3
4
5
6
7
8
9
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "quick"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "slow"));

const promises = [promise1, promise2, promise3];

Promise.any(promises).then((value) => console.log(value));

// Expected output: "quick"

Ox04 Promise.race()

在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。

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
function sleep(time, value, state) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (state === "兑现") {
return resolve(value);
} else {
return reject(new Error(value));
}
}, time);
});
}

const p1 = sleep(500, "一", "兑现");
const p2 = sleep(100, "二", "兑现");

Promise.race([p1, p2]).then((value) => {
console.log(value); // “二”
// 两个都会兑现,但 p2 更快
});

const p3 = sleep(100, "三", "兑现");
const p4 = sleep(500, "四", "拒绝");

Promise.race([p3, p4]).then(
(value) => {
console.log(value); // “三”
// p3 更快,所以它兑现
},
(error) => {
// 不会被调用
}
);

const p5 = sleep(500, "五", "兑现");
const p6 = sleep(100, "六", "拒绝");

Promise.race([p5, p6]).then(
(value) => {
// 不会被调用
},
(error) => {
console.error(error.message); // “六”
// p6 更快,所以它拒绝
}
);

参考

MDN Web 开发技术:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

作者

Dench

发布于

2024-06-27

更新于

2024-06-27

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×