Sto cercando di creare (ancora un altro) linguaggio che compaia in JavaScript. Una delle funzionalità che mi piacerebbe avere è la possibilità di eseguire le operazioni asincrone di JavaScript in modo sincrono (non esattamente in modo sincrono - senza bloccare il thread principale, ovviamente). Meno chiacchiere, altri esempi:
/* 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);
Qual è il modo più elegante per ricompilarlo in JS?
I criteri, ordinati per importanza:
- Prestazioni
- Compatibilità con le versioni precedenti
- Leggibilità del codice compilato (non molto importante)
Ci sono diversi modi possibili per implementarlo, quei tre mi sono venuti in mente:
-
Uso delle promesse:
-
f(); a( b() );
si trasformerebbe in -
f().then(function(){ return b() }).then(function(x){ a(x) });
- pros: relativamente semplice da implementare, polyfillable torna a ES3
- contro: creazione di una nuova funzione e un'istanza Proxy per ogni chiamata di funzione
-
-
-
f(); a( b() );
si trasformerebbe in -
yield f(); tmp = yield b(); yield a( tmp );
- pros: javascript più bello
- contro: creazione di proxy, generatori e iteratori su ogni passaggio, anche non polifunzionabile
- EDIT: infatti sono polifunibili utilizzando un altro ricompilatore (ad esempio Regenerator )
-
-
Uso di XMLHttpRequest sincrono:
- richiede uno script server che attende fino a un'altra chiamata da qualche altra parte nel codice
- pro: de facto nessun cambiamento nel codice, super facile da implementare
- contro: richiede lo script del server (= > nessuna portabilità, solo browser); inoltre, synchronous XMLHttpRequest blocca il thread in modo che non funzioni affatto
- EDIT: in realtà funzionerebbe all'interno di un lavoratore
Il problema principale è che non è possibile stabilire se una funzione è asincrona fino al runtime. Ciò si traduce in due soluzioni che almeno funzionano sono molto più lente del puro JS. Quindi chiedo:
Esistono modi migliori per implementare?
Dalle risposte:
Attendi la parola chiave (@ MI3Guy)
- C # way (che è buono !)
- introduce una nuova parola chiave (che può essere mascherata come una funzione (cittadino di prima classe) che ad esempio lancia se il programmatore prova a passarlo come argomento)
- Come sapere che la funzione è asincrona? Nessun'altra parola chiave!
- Ogni funzione che contiene la parola chiave
await
diventa asincrona? - Quando il codice raggiunge
await
, restituisce una promessa? Altro tratta come una funzione ordinaria?
- Ogni funzione che contiene la parola chiave