Estoy tratando de hacer (otro idioma) que se compila a JavaScript. Una de las características que me gustaría tener es la capacidad de realizar las operaciones asíncronas de JavaScript sincrónicamente (no exactamente sincrónicamente, sin bloquear el hilo principal, por supuesto). Menos charla, más ejemplos:
/* 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);
¿Cuál es la forma más elegante de volver a compilarlo en JS?
Los criterios, ordenados por importancia:
- Actuación
- Compatibilidad al revés
- Legibilidad compilada del código (no es realmente importante)
Hay varias formas posibles de implementarlo, esos tres me vinieron a la mente:
Usando promesas:
f(); a( b() );
se convertiría enf().then(function(){ return b() }).then(function(x){ a(x) });
- Pros: relativamente simple de implementar, polifilizable de vuelta a ES3
- contras: crear una nueva función y una instancia de Proxy para cada llamada de función
-
f(); a( b() );
se convertiría enyield f(); tmp = yield b(); yield a( tmp );
- pros: javascript más agradable
- contras: crear proxies, generadores e iteradores en cada paso, tampoco polifilables
- EDITAR: de hecho, son polifilables usando otro recompilador (por ejemplo, Regenerator )
Usando XMLHttpRequest sincrónico:
- solicite un script de servidor que espere hasta otra llamada de otro lugar en el código
- pros: de facto no hay cambios en el código, súper fácil de implementar
- contras: requiere script del servidor (=> no portabilidad, solo navegador); Además, XMLHttpRequest síncrono bloquea el hilo para que no funcione en absoluto
- EDITAR: en realidad funcionaría dentro de un trabajador
El principal problema es que no se puede saber si una función es asíncrona hasta el tiempo de ejecución. Eso da como resultado que las dos soluciones que al menos funcionan sean mucho más lentas que el JS puro. Entonces pregunto:
¿Hay mejores formas de implementar?
De las respuestas:
Aguardar palabra clave (@ MI3Guy)
- C # way (que es bueno !)
- introduce una nueva palabra clave (que se puede disfrazar como una función (ciudadano de primera clase) que, por ejemplo, arroja si el programador intenta pasarla como argumento)
- ¿Cómo saber que la función es asíncrona? No hay otras palabras clave!
- ¿Cada función que contiene la
await
palabra clave se vuelve asíncrona? - Cuando llega el código
await
, ¿devuelve una promesa? ¿Otra cosa se trata como una función ordinaria?
- ¿Cada función que contiene la
synchronously (without blocking the thread, of course)
Usted sigue usando esa palabra. No creo que signifique lo que crees que significa, porque sincrónicamente significa "bloquear el hilo".f(); a( b() );
se convertiría enf().then(b).then(a);
No incluye funciones.