跳到主要内容

Promise 深入解析与手写实现

1. Promise.all 详细用法

Promise.all 方法用于将多个 Promise 实例包装成一个新的 Promise。当所有输入的 Promise 都成功时,新的 Promise 才会成功,并返回一个包含所有结果的数组。如果任意一个输入的 Promise 失败,新的 Promise 会立即失败,并返回第一个失败的原因。

使用示例

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 100, 'foo');
});

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

在上述示例中,Promise.all 接收一个包含多个 Promise 的数组。当所有 Promise 都成功时,then 回调会被触发,输出结果数组。

错误处理

如果任意一个 Promise 被拒绝,Promise.all 会立即返回被拒绝的 Promise。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'error');
});
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values);
})
.catch((error) => {
console.error(error); // 输出: "error"
});

在这个例子中,promise2 被拒绝,导致 Promise.all 立即失败,并返回错误信息。

2. Promise.allSettled 详细用法

Promise.allSettled 方法接收一组 Promise,返回一个新的 Promise,该 Promise 在所有输入的 Promise 都已完成(无论是成功还是失败)后完成,并返回每个 Promise 的结果状态。

使用示例

const promise1 = Promise.resolve(42);
const promise2 = Promise.reject('错误发生');
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'foo'));

Promise.allSettled([promise1, promise2, promise3]).then((results) => {
console.log(results);
/*
输出:
[
{ status: 'fulfilled', value: 42 },
{ status: 'rejected', reason: '错误发生' },
{ status: 'fulfilled', value: 'foo' }
]
*/
});

Promise.allSettled 不会因为某个 Promise 被拒绝而立即失败,而是会等待所有 Promise 完成,并返回每个 Promise 的状态和结果。

3. Promise.race 详细用法

Promise.race 方法接收一组 Promise,并返回一个新的 Promise,该 Promise 会在第一个输入的 Promise 完成(无论是成功还是失败)时完成,并返回该 Promise 的结果或错误。

使用示例

const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'one'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'two'));

Promise.race([promise1, promise2]).then((value) => {
console.log(value); // 输出: "two"
});

在这个例子中,promise2promise1 先完成,因此 Promise.race 返回 promise2 的结果。

处理拒绝情况

const promise1 = new Promise((resolve, reject) => setTimeout(reject, 200, 'error'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'success'));

Promise.race([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // 输出: "error"
});

如果第一个完成的 Promise 是被拒绝的,Promise.race 会返回该错误。

4. Promise.any 详细用法

Promise.any 方法接收一组 Promise,并返回一个新的 Promise,该 Promise 在第一个成功的输入 Promise 完成时成功,并返回该 Promise 的结果。如果所有输入的 Promise 都被拒绝,则返回一个 AggregateError 错误。

使用示例

const promise1 = Promise.reject('失败');
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, '成功'));

Promise.any([promise1, promise2]).then((value) => {
console.log(value); // 输出: "成功"
});

在此示例中,虽然 promise1 被拒绝,但 promise2 成功完成,因此 Promise.any 返回 promise2 的结果。

所有 Promise 被拒绝

const promise1 = Promise.reject('失败1');
const promise2 = Promise.reject('失败2');

Promise.any([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // 输出: AggregateError: All promises were rejected
});

当所有输入的 Promise 都被拒绝时,Promise.any 返回一个包含所有错误的 AggregateError。

5. Promise.reject 和 Promise.resolve

Promise.resolvePromise.reject 是用于创建已解决或已拒绝状态的 Promise 的快捷方法。

Promise.resolve

Promise.resolve 用于创建一个立即解决的 Promise。

const resolvedPromise = Promise.resolve('成功');
resolvedPromise.then((value) => {
console.log(value); // 输出: "成功"
});

如果传入一个 Promise 对象,Promise.resolve 会返回该 Promise 对象。

const existingPromise = new Promise((resolve) => resolve('已有的 Promise'));
const resolvedPromise = Promise.resolve(existingPromise);
console.log(existingPromise === resolvedPromise); // 输出: true

Promise.reject

Promise.reject 用于创建一个立即拒绝的 Promise。

const rejectedPromise = Promise.reject('失败原因');
rejectedPromise.catch((reason) => {
console.error(reason); // 输出: "失败原因"
});

这两个方法常用于在异步函数中快速返回已解决或已拒绝的 Promise。

6. 手写 Promise.all 原理

实现 Promise.all 的核心在于同时执行多个 Promise,并在所有 Promise 都成功时返回它们的结果。如果任何一个 Promise 被拒绝,则立即返回该错误。

实现思路

  1. 接收一个包含多个 Promise 的可迭代对象。
  2. 返回一个新的 Promise。
  3. 遍历输入的 Promise,逐一执行并收集结果。
  4. 使用计数器跟踪已完成的 Promise 数量。
  5. 如果任意一个 Promise 被拒绝,立即拒绝新的 Promise。
  6. 当所有 Promise 都成功时,解决新的 Promise,并返回结果数组。

7. 手写 Promise.all 代码

function myPromiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是一个数组'));
}

const results = [];
let completed = 0;

if (promises.length === 0) {
return resolve([]);
}

promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
results[index] = value;
completed += 1;
if (completed === promises.length) {
resolve(results);
}
})
.catch((error) => {
reject(error);
});
});
});
}

代码解析

  • 输入验证: 首先检查输入是否为数组,如果不是,则返回一个 TypeError。
  • 结果收集: 使用 results 数组按照输入顺序存储每个 Promise 的结果。
  • 计数器: 使用 completed 变量跟踪已完成的 Promise 数量。
  • 异步处理: 使用 Promise.resolve 确保每个输入项都是一个 Promise。
  • 错误处理: 如果任何一个 Promise 被拒绝,立即拒绝整个 myPromiseAll

8. 手写 Promise.all 测试

// 测试用例
const promise1 = Promise.resolve(1);
const promise2 = 2;
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 3));

myPromiseAll([promise1, promise2, promise3])
.then((values) => {
console.log(values); // 输出: [1, 2, 3]
})
.catch((error) => {
console.error(error);
});

// 测试拒绝情况
const promise4 = Promise.reject('失败');

myPromiseAll([promise1, promise4, promise3])
.then((values) => {
console.log(values);
})
.catch((error) => {
console.error(error); // 输出: "失败"
});

测试说明

  • 成功场景: 所有 Promise 都成功,myPromiseAll 返回结果数组。
  • 失败场景: 存在一个被拒绝的 Promise,myPromiseAll 立即被拒绝,并返回错误信息。

9. 手写 Promise.race

Promise.race 方法接收一组 Promise,并返回一个新的 Promise,该 Promise 会在第一个输入的 Promise 完成(无论是成功还是失败)时完成,并返回该 Promise 的结果或错误。

实现思路

  1. 接收一个包含多个 Promise 的可迭代对象。
  2. 返回一个新的 Promise。
  3. 遍历输入的 Promise,逐一执行。
  4. 一旦有一个 Promise 完成(无论成功或失败),立即解决或拒绝新的 Promise。

10. 手写 Promise.race 代码测试

function myPromiseRace(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是一个数组'));
}

for (let promise of promises) {
Promise.resolve(promise)
.then((value) => {
resolve(value);
})
.catch((error) => {
reject(error);
});
}
});
}

// 测试用例
const racePromise1 = new Promise((resolve) => setTimeout(resolve, 500, 'one'));
const racePromise2 = new Promise((resolve) => setTimeout(resolve, 100, 'two'));

myPromiseRace([racePromise1, racePromise2])
.then((value) => {
console.log(value); // 输出: "two"
})
.catch((error) => {
console.error(error);
});

// 测试拒绝情况
const racePromise3 = new Promise((resolve, reject) => setTimeout(reject, 50, 'error'));
const racePromise4 = new Promise((resolve) => setTimeout(resolve, 100, 'success'));

myPromiseRace([racePromise3, racePromise4])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // 输出: "error"
});

测试说明

  • 第一个完成的 Promise: 无论是成功还是失败,myPromiseRace 都会返回第一个完成的 Promise 的结果或错误。
  • 拒绝优先: 如果第一个完成的是被拒绝的 Promise,myPromiseRace 会返回该错误。

11. 手写 Promise.allSettled

Promise.allSettled 方法接收一组 Promise,返回一个新的 Promise,该 Promise 在所有输入的 Promise 都已完成(无论是成功还是失败)后完成,并返回每个 Promise 的结果状态。

实现思路

  1. 接收一个包含多个 Promise 的可迭代对象。
  2. 返回一个新的 Promise。
  3. 遍历输入的 Promise,逐一执行并收集结果。
  4. 使用计数器跟踪已完成的 Promise 数量。
  5. 无论每个 Promise 是成功还是失败,都记录其状态和结果。
  6. 当所有 Promise 完成后,解决新的 Promise,并返回结果数组。

12. Promise.allSettled 代码测试

function myPromiseAllSettled(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是一个数组'));
}

const results = [];
let completed = 0;

if (promises.length === 0) {
return resolve([]);
}

promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
results[index] = { status: 'fulfilled', value };
})
.catch((reason) => {
results[index] = { status: 'rejected', reason };
})
.finally(() => {
completed += 1;
if (completed === promises.length) {
resolve(results);
}
});
});
});
}

// 测试用例
const settledPromise1 = Promise.resolve(1);
const settledPromise2 = Promise.reject('失败');
const settledPromise3 = new Promise((resolve) => setTimeout(resolve, 100, 3));

myPromiseAllSettled([settledPromise1, settledPromise2, settledPromise3])
.then((results) => {
console.log(results);
/*
输出:
[
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: '失败' },
{ status: 'fulfilled', value: 3 }
]
*/
})
.catch((error) => {
console.error(error);
});

测试说明

  • 混合结果: myPromiseAllSettled 会返回每个 Promise 的状态和结果,无论是成功还是失败。
  • 全部完成: 只有当所有 Promise 都完成后,myPromiseAllSettled 才会解决新的 Promise。

13. 手写 Promise.any

Promise.any 方法接收一组 Promise,并返回一个新的 Promise,该 Promise 在第一个成功的输入 Promise 完成时成功,并返回该 Promise 的结果。如果所有输入的 Promise 都被拒绝,则返回一个 AggregateError 错误。

实现思路

  1. 接收一个包含多个 Promise 的可迭代对象。
  2. 返回一个新的 Promise。
  3. 遍历输入的 Promise,逐一执行。
  4. 记录所有拒绝的原因。
  5. 一旦有一个 Promise 成功,立即解决新的 Promise 并返回结果。
  6. 如果所有 Promise 都被拒绝,拒绝新的 Promise 并返回 AggregateError。

14. 手写 Promise.any 代码测试

function myPromiseAny(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是一个数组'));
}

const errors = [];
let rejectedCount = 0;

if (promises.length === 0) {
return reject(new AggregateError([], 'All promises were rejected'));
}

promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
resolve(value);
})
.catch((error) => {
errors[index] = error;
rejectedCount += 1;
if (rejectedCount === promises.length) {
reject(new AggregateError(errors, 'All promises were rejected'));
}
});
});
});
}

// 测试用例
const anyPromise1 = Promise.reject('失败1');
const anyPromise2 = new Promise((resolve) => setTimeout(resolve, 100, '成功'));

myPromiseAny([anyPromise1, anyPromise2])
.then((value) => {
console.log(value); // 输出: "成功"
})
.catch((error) => {
console.error(error);
});

// 测试所有拒绝
const anyPromise3 = Promise.reject('失败2');
const anyPromise4 = Promise.reject('失败3');

myPromiseAny([anyPromise3, anyPromise4])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // 输出: AggregateError: All promises were rejected
});

测试说明

  • 成功场景: 任意一个 Promise 成功,myPromiseAny 返回该结果。
  • 全部拒绝: 所有 Promise 都被拒绝,myPromiseAny 返回 AggregateError。

15. 手写 Promise.last

Promise.last 是一个自定义的 Promise 方法,它会等待所有输入的 Promise 完成,并返回最后一个完成的 Promise 的结果。如果最后一个完成的 Promise 被拒绝,则返回该错误。

实现思路

  1. 接收一个包含多个 Promise 的可迭代对象。
  2. 返回一个新的 Promise。
  3. 遍历输入的 Promise,逐一执行。
  4. 记录每个 Promise 的完成顺序。
  5. 当所有 Promise 完成后,返回最后一个完成的 Promise 的结果或错误。

16. 手写 Promise.last 代码测试

function myPromiseLast(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是一个数组'));
}

if (promises.length === 0) {
return resolve();
}

let lastIndex = -1;
let completed = 0;

promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
if (index > lastIndex) {
lastIndex = index;
}
completed += 1;
if (completed === promises.length) {
resolve(promises[lastIndex]);
}
})
.catch((error) => {
if (index > lastIndex) {
lastIndex = index;
}
completed += 1;
if (completed === promises.length) {
reject(error);
}
});
});
});
}

// 测试用例
const lastPromise1 = new Promise((resolve) => setTimeout(resolve, 100, 'first'));
const lastPromise2 = new Promise((resolve) => setTimeout(resolve, 200, 'second'));
const lastPromise3 = new Promise((resolve) => setTimeout(resolve, 300, 'third'));

myPromiseLast([lastPromise1, lastPromise2, lastPromise3])
.then((value) => {
console.log(value); // 输出: "third"
})
.catch((error) => {
console.error(error);
});

// 测试最后一个被拒绝
const lastPromise4 = new Promise((resolve) => setTimeout(resolve, 100, 'first'));
const lastPromise5 = new Promise((resolve, reject) => setTimeout(reject, 200, 'error'));

myPromiseLast([lastPromise4, lastPromise5])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // 输出: "error"
});

测试说明

  • 成功场景: 返回最后一个完成的 Promise 的结果。
  • 拒绝场景: 如果最后一个完成的 Promise 被拒绝,返回该错误。

17. 手写 Promise.queue

Promise.queue 是一个自定义的 Promise 方法,用于控制一组异步任务的执行顺序,确保任务按照指定的顺序一个接一个地执行。

实现思路

  1. 接收一个包含异步任务的数组,每个任务返回一个 Promise。
  2. 按照数组顺序执行每个任务。
  3. 等待当前任务完成后再执行下一个任务。
  4. 返回一个包含所有任务结果的数组。

18. 手写并发请求题目

编写一个函数 fetchUrlsInQueue(urls, limit),该函数接受一个 URL 数组和并发限制数 limit,并按顺序发送 HTTP 请求,最多同时进行 limit 个请求。函数应返回一个包含所有请求结果的数组。

实现思路

  1. 使用一个队列来管理待执行的请求。
  2. 保持同时进行的请求数量不超过 limit
  3. 依次执行队列中的请求,并收集结果。
  4. 当所有请求完成后,返回结果数组。

19. 手写并发控制

function fetchUrlsInQueue(urls, limit) {
return new Promise((resolve, reject) => {
const results = [];
let inFlight = 0;
let currentIndex = 0;

function enqueue() {
if (currentIndex === urls.length && inFlight === 0) {
resolve(results);
return;
}

while (inFlight < limit && currentIndex < urls.length) {
const index = currentIndex;
const url = urls[currentIndex];
currentIndex += 1;
inFlight += 1;

fetch(url)
.then((response) => response.text())
.then((data) => {
results[index] = data;
inFlight -= 1;
enqueue();
})
.catch((error) => {
reject(error);
});
}
}

enqueue();
});
}

// 使用示例
const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3',
'https://jsonplaceholder.typicode.com/posts/4',
'https://jsonplaceholder.typicode.com/posts/5',
];

fetchUrlsInQueue(urls, 2)
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});

测试说明

  • 并发限制: 同时进行的请求数量不超过 limit
  • 结果顺序: 结果数组中的数据顺序与输入的 URL 顺序一致。

20. 使用闭包优化并发请求结果顺序

在并发请求中,由于请求的完成顺序不确定,使用闭包可以确保结果按照请求的顺序存储。

实现思路

  1. 使用闭包保存每个请求的索引。
  2. 在请求完成时,将结果存储到对应的索引位置。
  3. 确保最终结果数组的顺序与输入顺序一致。

21. 手写 Promisify

Promisify 是将基于回调的异步函数转换为返回 Promise 的函数的过程。

实现思路

  1. 接收一个基于回调的函数。
  2. 返回一个新的函数,该函数返回一个 Promise。
  3. 在新的函数中调用原始函数,并在回调中解析或拒绝 Promise。

实现代码

function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
if (error) {
return reject(error);
}
resolve(result);
});
});
};
}

// 使用示例
const fs = require('fs');

const readFileAsync = promisify(fs.readFile);

readFileAsync('example.txt', 'utf8')
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});

测试说明

  • 成功场景: 回调函数调用 resolve
  • 拒绝场景: 回调函数调用 reject

22. async、await 微任务代码输出 1

asyncawait 是用于简化 Promise 使用的语法糖。它们基于微任务队列,确保异步代码按预期执行。

示例代码

async function asyncFunction() {
console.log('开始');

const promise = new Promise((resolve) => {
setTimeout(() => {
resolve('完成');
}, 1000);
});

const result = await promise;
console.log(result);
}

asyncFunction();
console.log('同步代码');

输出说明

执行顺序如下:

  1. 输出: "开始"
  2. 输出: "同步代码"
  3. 等待 1 秒后输出: "完成"

这是因为 await 会等待 Promise 解析,但不会阻塞主线程,后续的同步代码会继续执行。

23. Promise A+ 规范

Promise A+ 是一个规范,定义了 Promise 的行为和状态转换。它确保了不同实现之间的一致性,使得 Promise 可以互操作。

主要内容

  • 状态: Promise 有三种状态:待定(pending)、已兑现(fulfilled)、已拒绝(rejected)。
  • then 方法: then 方法用于注册回调,接收两个参数:成功回调和失败回调。
  • 链式调用: then 方法返回一个新的 Promise,支持链式调用。
  • 错误传递: 异常会传递到下一个 catch 回调。
  • 解析过程: 当一个 Promise 被解析为另一个 Promise 时,必须遵循一定的解析规则,确保正确的状态转换。

重要规则

  1. then 方法必须返回一个新的 Promise
  2. 如果回调返回一个值,新 Promise 被解决为该值
  3. 如果回调抛出错误,新 Promise 被拒绝为该错误
  4. 如果回调返回一个 Promise,新 Promise 的状态取决于该 Promise

这些规则确保了 Promise 的行为符合预期,并且不同的实现可以互相兼容。

24. 手写 Promise

手写一个简单的 Promise 实现,遵循基本的 Promise 行为。

实现代码

class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];

const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => callback(value));
}
};

const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => callback(reason));
}
};

try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}

then(onFulfilled, onRejected) {
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
try {
const x = onFulfilled(this.value);
resolve(x);
} catch (error) {
reject(error);
}
}

if (this.state === 'rejected') {
try {
const x = onRejected(this.reason);
resolve(x);
} catch (error) {
reject(error);
}
}

if (this.state === 'pending') {
this.onFulfilledCallbacks.push((value) => {
try {
const x = onFulfilled(value);
resolve(x);
} catch (error) {
reject(error);
}
});

this.onRejectedCallbacks.push((reason) => {
try {
const x = onRejected(reason);
resolve(x);
} catch (error) {
reject(error);
}
});
}
});

return promise2;
}

catch(onRejected) {
return this.then(null, onRejected);
}
}

// 使用示例
const myPromise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
}, 1000);
});

myPromise
.then((value) => {
console.log(value); // 输出: "成功"
return '下一步';
})
.then((value) => {
console.log(value); // 输出: "下一步"
})
.catch((error) => {
console.error(error);
});

实现说明

  • 状态管理: 使用 state 属性跟踪 Promise 的状态。
  • 回调队列: 使用 onFulfilledCallbacksonRejectedCallbacks 数组存储回调函数,确保在异步情况下正确执行。
  • then 方法: 返回一个新的 Promise,实现链式调用。
  • 错误处理: 使用 try-catch 捕获执行过程中的错误,并通过 reject 传递。

25. Promise 链式调用与错误处理

Promise 的链式调用允许多个异步操作按顺序执行,每个操作的结果可以传递给下一个操作。错误处理则通过 catch 方法捕获链中任意位置的错误。

链式调用示例

new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
})
.then((value) => {
console.log(value); // 输出: 1
return value + 1;
})
.then((value) => {
console.log(value); // 输出: 2
return new Promise((resolve) => setTimeout(() => resolve(value + 1), 1000));
})
.then((value) => {
console.log(value); // 输出: 3
})
.catch((error) => {
console.error(error);
});

错误处理示例

new Promise((resolve, reject) => {
setTimeout(() => {
resolve('开始');
}, 500);
})
.then((value) => {
console.log(value); // 输出: "开始"
throw new Error('中间出错');
})
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('捕获错误:', error.message); // 输出: "捕获错误: 中间出错"
});

多重错误处理

在链式调用中,错误可以在任意位置被捕获。以下示例展示了多个 catch 的用法。

new Promise((resolve, reject) => {
resolve('任务1');
})
.then((value) => {
console.log(value); // 输出: "任务1"
return '任务2';
})
.then((value) => {
console.log(value); // 输出: "任务2"
throw new Error('任务3 出错');
})
.catch((error) => {
console.error('捕获错误:', error.message); // 输出: "捕获错误: 任务3 出错"
return '错误处理后继续';
})
.then((value) => {
console.log(value); // 输出: "错误处理后继续"
})
.catch((error) => {
console.error(error);
});

在此示例中,第一个 catch 捕获了第三个任务的错误,并通过返回一个值继续了链式调用。第二个 catch 只会捕获后续链中的错误。