Tôi đang cố gắng tạo ngôn ngữ (một ngôn ngữ khác) biên dịch sang JavaScript. Một trong những tính năng tôi muốn có là khả năng thực hiện các hoạt động không đồng bộ của JavaScript một cách đồng bộ (tất nhiên là không đồng bộ - mà không chặn luồng chính, tất nhiên). Ít nói hơn, nhiều ví dụ hơn:
/* These two snippets should do exactly the same thing */
// the js way
var url = 'file.txt';
fetch(url)
.then(function (data) {
data = "(" + data + ")";
return sendToServer(data);
}).then(function (response) {
console.log(response);
});
// synchronous-like way
var url = 'file.txt';
var response = sendToServer("(" + fetch(url) + ")");
console.log(response);
Cách thanh lịch nhất để biên dịch nó trở lại với JS là gì?
Các tiêu chí, được sắp xếp theo mức độ quan trọng:
- Hiệu suất
- Khả năng tương thích ngược
- Mã biên dịch dễ đọc (không thực sự quan trọng)
Có một số cách có thể để thực hiện nó, ba cách đó xuất hiện trong đầu tôi:
Sử dụng lời hứa:
f(); a( b() );
sẽ biến thànhf().then(function(){ return b() }).then(function(x){ a(x) });
- ưu điểm: tương đối đơn giản để thực hiện, polyfillable trở lại ES3
- Nhược điểm: tạo một hàm mới và một thể hiện Proxy cho mỗi lệnh gọi hàm
-
f(); a( b() );
sẽ biến thànhyield f(); tmp = yield b(); yield a( tmp );
- ưu: javascript đẹp hơn
- Nhược điểm: tạo proxy, trình tạo và lặp trên mỗi bước, cũng không phải là polyfillable
- EDIT: trên thực tế chúng là polyfillable khi sử dụng một trình biên dịch lại khác (ví dụ: Regenerator )
Sử dụng XMLHttpRequest đồng bộ:
- yêu cầu tập lệnh máy chủ chờ cho đến khi có cuộc gọi khác từ nơi khác trong mã
- ưu điểm: thực tế không có thay đổi nào trong mã, siêu dễ thực hiện
- Nhược điểm: yêu cầu tập lệnh máy chủ (=> không có tính di động, chỉ dành cho trình duyệt); hơn nữa, XMLHttpRequest đồng bộ chặn luồng để nó không hoạt động
- EDIT: Nó thực sự sẽ hoạt động bên trong Công nhân
Vấn đề chính là người ta không thể biết nếu một chức năng không đồng bộ cho đến khi chạy. Điều đó dẫn đến hai giải pháp ít nhất là làm việc chậm hơn rất nhiều so với JS thuần túy. Vì vậy tôi hỏi:
Có cách nào tốt hơn để thực hiện?
Từ câu trả lời:
Đang chờ từ khóa (@ MI3Guy)
- Cách C # ( tốt !)
- giới thiệu một từ khóa mới (có thể được ngụy trang thành một hàm (công dân hạng 1), ví dụ như ném nếu lập trình viên cố gắng vượt qua nó như một đối số)
- Làm thế nào để biết chức năng đó không đồng bộ? Không có từ khóa khác!
- Mọi chức năng có chứa
await
từ khóa trở nên không đồng bộ? - Khi mã được
await
, nó trả lại một lời hứa? Khác coi như một chức năng bình thường?
- Mọi chức năng có chứa
f(); a( b() );
sẽ chuyển sang f().then(b).then(a);
Bạn không kèm theo các chức năng.
synchronously (without blocking the thread, of course)
Bạn tiếp tục sử dụng từ đó. Tôi không nghĩ nó có nghĩa là những gì bạn nghĩ, bởi vì đồng bộ có nghĩa là "chặn chuỗi".