Thực thi tuần tự JavaScript

Tôi thích thư viện Promise mới đi kèm với ES6, mặc dù có một thứ đã bị loại bỏ, một chức năng để thực hiện tuần tự nhiều lời hứa

Chúng ta có thể sử dụng một thư viện như Q, Bluebird, RSVP. js, Không đồng bộ, v.v. hoặc chúng ta có thể tự làm. Tôi thực sự chỉ cần một chức năng duy nhất và có vẻ hơi nặng nề khi nhập toàn bộ thư viện cho một chức năng, đó là lý do tại sao tôi tạo ra cái này

Một đặc điểm của Promise là nó thực thi ngay lập tức. Điều này thực sự chống lại chúng tôi, chúng tôi sẽ cần các Lời hứa thực thi khi chúng tôi sẵn sàng để nó thực thi

Cách tôi đã làm điều này là chuyển đổi từng Lời hứa thành một chức năng xuất xưởng. Chức năng xuất xưởng sẽ là một chức năng đơn giản sẽ trả về một Lời hứa. Bây giờ Lời hứa của chúng tôi sẽ thực hiện khi chúng tôi quyết định

Đối với ví dụ giả tạo *ho* này, tôi đã quyết định sử dụng phương thức ajax của jQuery như lời hứa của mình

// some dummy urls to resolve
const urls = ['/url1', '/url2', '/url3']

// convert each url to a function that returns an ajax call
const funcs = urls.map(url => () => $.ajax(url))

Giải quyết vấn đề này hơi phức tạp và tôi thấy nó giúp tôi suy nghĩ trước một chút về những gì hàm của chúng ta sẽ xuất ra. Có lẽ một cái gì đó như thế này

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]

Tôi cũng muốn lời hứa cuối cùng trả về một mảng chứa kết quả của từng lời hứa

Đây là phần phức tạp nhất. Tôi cần bắt đầu mỗi lời hứa với một mảng trống [] và sau đó nối kết quả của từng lời hứa với mảng đó. Gắn bó với tôi, tôi sẽ cố gắng hết sức để phá vỡ nó

Tôi sẽ bắt đầu Lời hứa này với giá trị ban đầu của một mảng trống như thế này Promise.resolve([]). Sau đó, thực hiện từng chức năng xuất xưởng bằng chức năng Promise's

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
0

Để đơn giản, ví dụ này chỉ giải quyết chỉ mục

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
1of func. Chúng tôi sẽ làm phần còn lại sau

// start our promise off with an empty array. this becomes all.
Promise.resolve([])
// all is the array we will append each result to.
.then(all => {
return funcs[0]().then(result => {
// concat the resolved promise result to all
return all.concat(result)
})
})

Khối mã này có thể được thể hiện điều này theo cách nhỏ gọn hơn bằng cách xóa tất cả các

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
2,
Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
3 và
Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
4 khỏi mã của chúng tôi

________số 8_______

Một mẹo hay để loại bỏ chức năng mũi tên đó là gọi trực tiếp

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
5 như thế này

Promise.resolve([])
.then(all => funcs[0]().then(Array.prototype.concat.bind(all)))

Và cuối cùng, đây sẽ là đầu ra của chức năng của chúng tôi

Promise.resolve([])
.then(x => funcs[0]().then(Array.prototype.concat.bind(x)))
.then(x => funcs[1]().then(Array.prototype.concat.bind(x)))
.then(x => funcs[2]().then(Array.prototype.concat.bind(x)))

Điều đó không tệ lắm phải không?

Chúng ta có thể sử dụng vòng lặp

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
6 (nhưng nó không hoạt động tốt lắm), chúng ta cũng có thể sử dụng đệ quy, nhưng điều tôi thực sự thích cho vấn đề này là
Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
7

Bất cứ khi nào bạn cần chuyển đổi một danh sách thành một đối tượng, hãy xem xét sử dụng giảm

Hàm

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
8 của chúng ta sẽ nhận một mảng các hàm xuất xưởng (mỗi hàm trả về một Lời hứa) và rút gọn chúng thành một chuỗi Lời hứa duy nhất được biểu thị ở trên

Giá trị ban đầu của chúng tôi là Promise.resolve([]) được chuyển vào phương thức rút gọn của chúng tôi như thế này

const promiseSerial = funcs =>
funcs.reduce((promise, func) => ???, Promise.resolve([]))

Phần cuối cùng là khái quát hóa một trong những Lời hứa của chúng tôi về

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
0 từ phía trên và cập nhật một số tên đối số. (phần mới in đậm)

const promiseSerial = funcs =>
funcs.reduce((promise, func) =>
promise.then(result =>
func().then(Array.prototype.concat.bind(result))),
Promise.resolve([]))

Đó là nó. Một chức năng khá đơn giản… cào mà… ngắn sẽ giải quyết các Lời hứa một cách tuần tự

Cuối cùng, hãy tát tất cả lại với nhau

Bây giờ chúng tôi đã loại bỏ nhu cầu cài đặt thư viện của bên thứ 3 với chức năng

Promise.resolve()
.then(x => funcs[0]()) // resolve func[0]
.then(x => funcs[1]()) // resolve func[1]
.then(x => funcs[2]()) // resolve func[2]
8 mới sáng bóng của chúng tôi

Chào. Bạn thực sự đã đi đến cuối bài viết này

Trường hợp sử dụng của bạn để giải quyết các lời hứa một cách tuần tự là gì?

Tôi biết đó là một việc nhỏ, nhưng nó khiến tôi vui vẻ cả ngày khi nhận được những thông báo theo dõi đó trên Medium và Twitter (@joelnet). Hoặc nếu bạn nghĩ rằng tôi đầy rác rưởi, hãy cho tôi biết trong phần bình luận bên dưới

Chúc mừng

Những bài viết liên quan

Suy nghĩ lại về JavaScript. Break là GOTO của các vòng lặp

Trong bài viết trước của tôi, Cái chết của vòng lặp for, tôi đã cố gắng thuyết phục bạn từ bỏ vòng lặp for để có một vòng lặp nhiều chức năng hơn…

trung bình. com

Suy nghĩ lại về JavaScript. Cái chết của vòng lặp For

Vòng lặp for của JavaScript đã phục vụ chúng ta rất tốt, nhưng nó hiện đã lỗi thời và nên được gỡ bỏ để nhường chỗ cho các chức năng mới hơn…

hackernoon. com

Suy nghĩ lại về JavaScript. Câu lệnh if

Suy nghĩ chức năng đã mở mang đầu óc của tôi về lập trình

trung bình. com

Hacker Noon là cách hacker bắt đầu buổi chiều của họ. Chúng tôi là thành viên của gia đình @AMI. Chúng tôi hiện đang chấp nhận đệ trình và sẵn lòng thảo luận về các cơ hội quảng cáo và tài trợ

Nếu bạn thích câu chuyện này, chúng tôi khuyên bạn nên đọc những câu chuyện công nghệ mới nhất của chúng tôi và những câu chuyện công nghệ thịnh hành. Cho đến lần sau, đừng coi thực tế của thế giới là điều hiển nhiên

JavaScript có được thực thi tuần tự không?

Điểm mấu chốt là mọi thứ xảy ra bên trong ngăn xếp thực thi chức năng là tuần tự . Đây là phần Đồng bộ của JavaScript. Chuỗi chính của JavaScript đảm bảo rằng nó xử lý mọi thứ trong ngăn xếp trước khi bắt đầu xem xét bất kỳ thứ gì ở nơi khác.

JavaScript thực thi theo thứ tự nào?

Thứ tự thực hiện là gì? .
ngăn xếp
Vòng lặp sự kiện
Hàng đợi nhiệm vụ
WebAPI/Tài nguyên bên ngoài

JavaScript có thực thi từng dòng không?

Trong Giai đoạn thực thi mã, JavaScript là một ngôn ngữ luồng đơn lại chạy qua từng dòng mã và cập nhật các giá trị của hàm và .

Hàm gọi lại trong JavaScript là gì?

Một hàm gọi lại JavaScript là một hàm sẽ được thực thi sau khi một hàm khác đã thực thi xong . Một định nghĩa chính thức hơn sẽ là - Bất kỳ hàm nào được truyền dưới dạng đối số cho hàm khác để nó có thể được thực thi trong hàm khác đó được gọi là hàm gọi lại.