Promise.withResolvers()
Baseline
2024
Newly available
Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Phương thức tĩnh Promise.withResolvers() trả về một đối tượng chứa một Promise mới và hai hàm để resolve hoặc reject nó, tương ứng với hai tham số được truyền cho executor của constructor Promise().
Cú pháp
Promise.withResolvers()
Tham số
Không có.
Giá trị trả về
Một đối tượng thuần chứa các thuộc tính sau:
Mô tả
Promise.withResolvers() hoàn toàn tương đương với đoạn mã sau:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
Ngoại trừ nó ngắn gọn hơn và không yêu cầu sử dụng let.
Điểm khác biệt chính khi sử dụng Promise.withResolvers() là các hàm resolve và reject giờ đây nằm trong cùng phạm vi với chính promise, thay vì chỉ được tạo và sử dụng một lần bên trong executor. Điều này có thể cho phép một số trường hợp sử dụng nâng cao hơn, chẳng hạn như khi tái sử dụng chúng cho các sự kiện lặp lại, đặc biệt là với streams và queues. Điều này cũng thường dẫn đến ít lồng nhau hơn so với việc bọc nhiều logic bên trong executor.
Promise.withResolvers() là generic và hỗ trợ phân lớp con, có nghĩa là nó có thể được gọi trên các lớp con của Promise, và kết quả sẽ chứa một promise của kiểu lớp con. Để làm vậy, constructor của lớp con phải triển khai cùng chữ ký với constructor Promise() — chấp nhận một hàm executor duy nhất có thể được gọi với các callback resolve và reject làm tham số.
Ví dụ
>Chuyển đổi một stream thành async iterable
Trường hợp sử dụng của Promise.withResolvers() là khi bạn có một promise cần được resolve hoặc reject bởi một event listener không thể được bọc bên trong executor của promise. Ví dụ sau chuyển đổi một readable stream của Node.js thành một async iterable. Mỗi promise ở đây đại diện cho một batch dữ liệu có sẵn, và mỗi khi batch hiện tại được đọc, một promise mới được tạo cho batch tiếp theo. Lưu ý rằng các event listener chỉ được gắn một lần, nhưng thực tế gọi một phiên bản khác nhau của hàm resolve và reject mỗi lần.
async function* readableToAsyncIterable(stream) {
let { promise, resolve, reject } = Promise.withResolvers();
stream.on("error", (error) => reject(error));
stream.on("end", () => resolve());
stream.on("readable", () => resolve());
while (stream.readable) {
await promise;
let chunk;
while ((chunk = stream.read())) {
yield chunk;
}
({ promise, resolve, reject } = Promise.withResolvers());
}
}
Gọi withResolvers() trên một constructor không phải Promise
Promise.withResolvers() là một phương thức generic. Nó có thể được gọi trên bất kỳ constructor nào triển khai cùng chữ ký như constructor Promise(). Ví dụ, chúng ta có thể gọi nó trên một constructor truyền console.log làm hàm resolve và reject cho executor:
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.withResolvers() just returns them, as is.
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const { promise, resolve, reject } = Promise.withResolvers.call(NotPromise);
resolve("hello");
// Logs: Resolved hello
Đặc tả
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-promise.withResolvers> |