cuốn sách gpt4 ai đã làm

Triển khai PromiseA+ viết tay, dễ dàng vượt qua 872 trường hợp sử dụng

In lại Tác giả: Sahara Thời gian cập nhật: 27-12-2024 20:40:57 57 4
mua khóa gpt4 Nike

Triển khai Promise/A+ viết tay, dễ dàng vượt qua 872 trường hợp sử dụng

Tham khảo thông số kỹ thuật: Thông số kỹ thuật Promise/A+ - Phiên bản tiếng Trung.

Công cụ kiểm tra: https://github.com/promises-aplus/promises-tests.

Lời nói đầu

Từ khi tiếp xúc với Promise đến nay, tác giả đã trải qua quá trình này:

  1. Hiểu các thông số kỹ thuật khác nhau của Promise, bao gồm Promise/A+, nhưng không biết nội dung cụ thể của nó.
  2. Tôi đã nghiên cứu các cách triển khai Promise trước đây và cố gắng tự viết chúng nhưng tôi thường gặp phải sự cố trong quá trình thử nghiệm.
  3. Sau khi suy nghĩ kỹ, tại sao giá trị trả về có thể xác định được trạng thái của Promise? Tại sao cuộc gọi theo chuỗi lại trả về một Lời hứa mới thay vì lời hứa này? Tôi rơi vào tình trạng bối rối sâu sắc.
  4. Có lẽ do kiên trì nên tôi đã nghiên cứu sâu về đặc tả Promise/A+. Mặc dù ban đầu tôi còn bối rối vì một số thuật ngữ nhưng tôi vẫn tiếp tục học.
  5. Dịch từng câu một, hiểu chuẩn rồi dần dần làm quen. Từ nhu cầu ban đầu là viết mã theo thông số kỹ thuật, đến giờ có thể viết Promise bằng tay, quá trình này thật thú vị và nó cũng giúp tôi hiểu sâu hơn về một số phương pháp phổ biến của Promise.

Nếu bạn cũng đang học Promise và gặp khó khăn, tôi khuyên bạn nên tham khảo thông số kỹ thuật và code để hiểu nó.

hoàn thành

Trước khi đọc mã, bạn cần hiểu rằng các nhận xét trong mã không được thêm ngẫu nhiên và mỗi nhận xét tương ứng với các mệnh đề cụ thể trong đặc tả Promise/A+.

Về đặc điểm kỹ thuật, nó chủ yếu bao gồm các phần sau:

  1. Bạn có thể hiểu đơn giản các thuật ngữ chuyên nghiệp.
  2. Thông số kỹ thuật chi tiết cần được hiểu rõ từng dòng, bao gồm:
    • 2.1 Ba trạng thái của Lời hứa: đang chờ xử lý, đã hoàn thành và bị từ chối.
    • 2.2 Lời hứa sau đó Việc thực hiện phương pháp, các thao tác cần được thực hiện ở các trạng thái khác nhau.
    • 2.3 Hành vi ra quyết định của Promise đối với một giá trị nhất định còn được gọi là quy trình giải quyết Promise.

Do đó, bạn sẽ thấy các thẻ tương tự như sau trong phần nhận xét:

// 2.1 (2)(2)

Nó đại diện cho nội dung thứ hai dưới số sê-ri thứ hai ở trạng thái Promise 2.1 tương ứng với thông số kỹ thuật.

Tức là số sê-ri tiêu đề và số sê-ri nội dung… .

Trong đoạn mã bên dưới, mặc dù không có chú thích nào bao gồm tất cả các thuật ngữ đặc tả nhưng chúng được triển khai ngầm.

Mã hoàn chỉnh như sau:

function MyPromise(executor) { this.state = 'pending' // 2.1 (1)(1) Trạng thái ban đầu có thể được chuyển đổi sang hai trạng thái còn lại, cụ thể là hoàn thành hoặc từ chối this.value = null // 2.1 (2)( 2) phải có giá trị bất biến this.reason = null // 2.1 (3)(2) phải có lý do bất biến this.onFulfilledCallbacks = [] this.onRejectedCallbacks = [] const Resolve = (value) => { if (this.state !== 'pending') return this.state = 'fulfilled' this.value = value // 2.2 (6)(1 ) Khi lời hứa được thực hiện, tất cả các lệnh gọi lại onFulfilled tương ứng phải được thực thi theo thứ tự mà chúng gọi sau đó là this.onFulfilledCallbacks.forEach((callback) => callback(this.value)) } const từ chối = (lý do) => { if (this.state !== 'pending') return this.state = 'rejected' this.reason = Reason // 2.2 (6)(2 ) Khi một lời hứa bị từ chối, tất cả các lệnh gọi lại onRejected tương ứng phải được thực thi theo thứ tự mà chúng gọi sau đó là this.onRejectedCallbacks.forEach((callback) => callback(this.reason)) } // Nếu việc xử lý ngoại lệ được thực hiện trên Promise executor được trả về thì bước này là tùy chọn try { executor(resolve,ject) } Catch (e) { từ chối(e) } } // 2.2 (6) Phương thức nguyên mẫu, Đảm bảo rằng thì trên cùng một Promise có thể được gọi nhiều lần theo các trạng thái khác nhau MyPromise.prototype.then = function (onFulfilled, onRejected) { // 2.2 (1) onFulfilled và các tham số onRejected là tùy chọn và sẽ bị bỏ qua nếu chúng không phải là hàm (có một sửa đổi nhỏ ở đây, nhưng về cơ bản vẫn tuân thủ đặc tả, trả về một giá trị hoặc đưa ra lệnh gọi chuỗi quyết định ngoại lệ) const realOnFulfilled = typeof onFulfilled === 'function ' ? onFulfilled // 2.2 (2) : (value) => { return value } const realOnRejected = typeof onRejected === 'function' ? onRejected // 2.2 (3) : (lý do) => { lý do ném } // 2.2 (7) thì một lời hứa phải được trả lại let Promise2 = new MyPromise((resolve, từ chối) => { if (this.state === 'fulfilled') { // 2.2 (4 ) Phải được gọi khi ngăn xếp ngữ cảnh thực thi chỉ chứa mã nền tảng queueMicrotask(() => { try { // 2.2 (5) Phải được gọi dưới dạng hàm let x = realOnFulfilled(this.value) // 2.2 (7)(1) Chạy quy trình phân giải Lời hứa [[Resolve]](promise2, x) dựa trên giá trị trả về x, cũng chứa thông số kỹ thuật 2.2 (7)(3) Quy trình giải quyếtPromise(promise2, x, giải quyết, từ chối ) } Catch (e) { // 2.2 (7)(2) ném ra ngoại lệ e, thì Promise2 phải bị từ chối với lý do là e, 2.2 cũng được đưa vào đây (7)(4) đang xử lý (hàm mặc định ở trên sẽ đưa ra lý do khi nó không phải là một hàm, bắt lỗi từ chối ở đây, nó không được triển khai sao) từ chối(e) } }) } else if (this.state === 'rejected ') { queueMicrotask(() => { try { let x = realOnRejected(this.reason) ResolvePromise(promise2, x, giải quyết, từ chối) } Catch (e) { từ chối(e) } }) } else if (this.state === 'pending') { // Nếu việc thực thi không đồng bộ trong Promise diễn ra sau và sau đó được thêm vào trước, bước này có thể đảm bảo rằng lệnh gọi lại không bị bỏ qua. this.onFulfilledCallbacks.push(() => { queueMicrotask(() => { try { let x = realOnFulfilled(this.value) giải quyếtPromise(promise2, x, giải quyết, từ chối) } bắt (e) { từ chối(e) } }) }) this.onRejectedCallbacks.push(() => { queueMicrotask(() => { try { let x = realOnRejected(this.reason) giải quyếtPromise(promise2, x, giải quyết, từ chối) } bắt (e) { từ chối(e) } }) }) } }) // 2.2 (7) trả về lời hứa2 } hàm giải quyếtPromise(promise, x, giải quyết, từ chối) { // 2.3 (1) Nếu lời hứa và x trỏ đến cùng một đối tượng, TypeError từ chối lời hứa là lý do, ở đây ném hoặc trả lại Từ chối có thể được sử dụng nếu (promise === x) Throw new TypeError('promise và return value are likea') // Theo đặc điểm của Promise hoặc đối tượng có thể then chốt, nhánh có thể được đánh giá trực tiếp như sau if (x != = null && (typeof x === 'function' || typeof x === 'object')) { // 2.3 (3)(3)(3) và 2.3 (3)(4)(1) Biến đặc biệt vấn đề ưu tiên cuộc gọi let known = false try { const then = x.then if (typeof then === 'function') { // 2.3 (3)(3) if then là một hàm, sau đó gọi nó bằng x như sau.call( x, (y) => { if (gọi) return gọi = true // 2.3 (3)(3)(1) ResolvePromise(promise, y, Resolve , từ chối) }, (r) => { if (được gọi) return được gọi = true // 2.3 (3)(3)(2) từ chối(r) } ) } else { // 2.3 (3)(4) x is Đối tượng không thể sử dụng được (nếu then không phải là hàm, hãy sử dụng x để thực hiện lời hứa) Resolve(x) } } Catch (e) { if (được gọi) return được gọi = true // 2.3 (3)(2) Nếu một ngoại lệ e được ném ra khi truy xuất thuộc tính x.then, hãy từ chối lời hứa với e là lý do // 2.3 (3)(3)(4)(2) Nếu một ngoại lệ được ném ra khi gọi thì hãy từ chối lời hứa với e là lý do từ chối( e) } } else { // 2.3 (4) Nếu x không phải là đối tượng hay hàm, hãy sử dụng x để thực hiện lời hứa // x là null không xác định, giá trị cơ bản, v.v. } // Hiển thị một giao diện để cung cấp các phương thức tĩnh để kiểm tra MyPromise.deferred = function () { const result = {} result.promise = new MyPromise((resolve, chối) => { result.resolve = Resolve result.reject = chối }) return result } module.exports = MyPromise

Cuối cùng, bài viết này về việc triển khai PromiseA+ viết tay và sự dễ dàng vượt qua 872 trường hợp sử dụng sẽ kết thúc tại đây. Nếu bạn muốn biết thêm về việc triển khai PromiseA+ viết tay và sự dễ dàng vượt qua 872 trường hợp sử dụng, vui lòng tìm kiếm các bài viết của CFSDN hoặc tiếp tục. duyệt các bài viết liên quan tôi hy vọng tất cả các bạn sẽ ủng hộ blog của tôi trong tương lai! .

57 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress