Đây là cách tôi nghĩ bạn nên làm.
tách chuỗi
Bởi vì cả hai chức năng sẽ được sử dụng AmazingData , điều hợp lý là có chúng trong một chức năng chuyên dụng. Tôi thường làm điều đó mỗi khi tôi muốn sử dụng lại một số dữ liệu, vì vậy nó luôn hiện diện dưới dạng một hàm đối số.
Vì ví dụ của bạn đang chạy một số mã, tôi sẽ cho rằng nó được khai báo tất cả bên trong một hàm. Tôi sẽ gọi nó là toto () . Sau đó, chúng ta sẽ có một hàm khác sẽ chạy cả afterSomething () và afterSomethingElse () .
function toto() {
return somethingAsync()
.then( tata );
}
Bạn cũng sẽ nhận thấy rằng tôi đã thêm một câu lệnh trả lại vì nó thường là cách để đi với Promises - bạn luôn trả lại một lời hứa để chúng tôi có thể tiếp tục xâu chuỗi nếu cần. Ở đây, somethingAsync () sẽ tạo ra AmazingData và nó sẽ có sẵn ở mọi nơi bên trong hàm mới.
Bây giờ, hàm mới này sẽ trông như thế nào thường phụ thuộc vào processAsync () cũng không đồng bộ ?
processAsync không bất đồng bộ
Không có lý do gì để phức tạp hóa mọi thứ nếu processAsync () không phải là không đồng bộ. Một số mã tuần tự tốt cũ sẽ tạo ra nó.
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Lưu ý rằng không quan trọng nếu afterSomethingElse () đang làm điều gì đó không đồng bộ hay không. Nếu đúng như vậy, một lời hứa sẽ được trả lại và chuỗi có thể tiếp tục. Nếu không, thì giá trị kết quả sẽ được trả về. Nhưng vì hàm được gọi từ then () , giá trị sẽ được bao bọc thành một lời hứa (ít nhất là trong Javascript thô).
processAsync không đồng bộ
Nếu processAsync () không đồng bộ, mã sẽ trông hơi khác một chút. Ở đây chúng ta coi afterSomething () và afterSomethingElse () sẽ không được sử dụng lại ở bất kỳ nơi nào khác.
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
Tương tự như trước cho afterSomethingElse () . Nó có thể không đồng bộ hoặc không. Một lời hứa sẽ được trả lại, hoặc một giá trị được bao bọc thành một lời hứa đã được giải quyết.
Phong cách viết mã của bạn khá gần với những gì tôi thường làm, đó là lý do tại sao tôi đã trả lời ngay cả sau 2 năm. Tôi không phải là một fan hâm mộ lớn của việc có các chức năng ẩn danh ở khắp mọi nơi. Tôi thấy nó khó đọc. Ngay cả khi nó khá phổ biến trong cộng đồng. Nó giống như chúng ta đã thay thế địa ngục gọi lại bằng một luyện ngục hứa hẹn .
Tôi cũng muốn giữ tên của các chức năng trong đó ngắn. Chúng sẽ chỉ được định nghĩa cục bộ. Và hầu hết thời gian họ sẽ gọi một hàm khác được định nghĩa ở nơi khác - để có thể tái sử dụng - để thực hiện công việc. Tôi thậm chí còn làm điều đó đối với các hàm chỉ có 1 tham số, vì vậy tôi không cần phải nhập và xuất hàm khi thêm / bớt một tham số vào chữ ký hàm.
Ví dụ ăn uống
Đây là một ví dụ:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
Đừng tập trung quá nhiều vào Promise.resolve () . Nó chỉ là một cách nhanh chóng để tạo ra một lời hứa đã được giải quyết. Những gì tôi cố gắng đạt được bằng cách này là có tất cả mã tôi đang chạy ở một vị trí duy nhất - ngay bên dưới chúng . Tất cả các chức năng khác có tên mô tả hơn đều có thể sử dụng lại được.
Hạn chế của kỹ thuật này là nó đang xác định rất nhiều chức năng. Nhưng đó là một nỗi đau cần thiết mà tôi sợ để tránh có những chức năng ẩn danh khắp nơi. Và rủi ro là gì: tràn ngăn xếp? (đùa!)
Sử dụng mảng hoặc đối tượng như được định nghĩa trong các câu trả lời khác cũng sẽ hoạt động. Theo một cách nào đó, đây là câu trả lời do Kevin Reid đề xuất .
Bạn cũng có thể sử dụng bind () hoặc Promise.all () . Lưu ý rằng họ vẫn sẽ yêu cầu bạn tách mã của mình.
sử dụng ràng buộc
Nếu bạn muốn giữ các hàm của mình có thể sử dụng lại được nhưng không thực sự cần giữ lại những gì bên trong thì bạn có thể sử dụng bind () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Để đơn giản, bind () sẽ thêm trước danh sách các args (ngoại trừ args đầu tiên) vào hàm khi nó được gọi.
sử dụng Promise.all
Trong bài đăng của bạn, bạn đã đề cập đến việc sử dụng spread () . Tôi chưa bao giờ sử dụng framework mà bạn đang sử dụng, nhưng đây là cách bạn có thể sử dụng nó.
Một số người tin rằng Promise.all () là giải pháp cho mọi vấn đề, vì vậy tôi đoán nó xứng đáng được đề cập.
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
Bạn có thể chuyển dữ liệu đến Promise.all () - lưu ý sự hiện diện của mảng - miễn là các hứa, nhưng đảm bảo không có hứa nào bị lỗi nếu không nó sẽ ngừng xử lý.
Và thay vì xác định các biến mới từ đối số args , bạn có thể sử dụng spread () thay vì then () cho tất cả các loại công việc tuyệt vời.