Come scrivere funzioni asincrone per Node.js

Ho provato a cercare come scrivere esattamente le funzioni asincrone. Dopo un sacco di aratura attraverso molta documentazione, non mi è ancora chiaro.

Come scrivere funzioni asincrone per il nodo? Come dovrei implementare correttamente la gestione degli eventi di errore?

Un altro modo per porre la mia domanda sarebbe questo: come dovrei interpretare la seguente funzione?

var async_function = function(val, callback){ process.nextTick(function(){ callback(val); }); }; 

Inoltre, ho trovato interessante questa domanda su SO (“Come posso creare una funzione asincrona non bloccante in node.js?”). Non mi sembra che abbia ancora ricevuto una risposta.

Sembra che tu stia confondendo l’I / O asincrono con le funzioni asincrone. node.js utilizza l’IO asincrono non bloccante perché l’I / O non bloccante è migliore. Il modo migliore per capirlo è andare a vedere alcuni video di Ryan Dahl.

Come scrivere funzioni asincrone per il nodo?

Basta scrivere le normali funzioni, l’unica differenza è che non vengono eseguite immediatamente ma passate in giro come callback.

Come devo implementare correttamente la gestione degli eventi di errore

Generalmente le API ti danno un callback con un err come primo argomento. Per esempio

 database.query('something', function(err, result) { if (err) handle(err); doSomething(result); }); 

È un modello comune.

Un altro modello comune è on('error') . Per esempio

 process.on('uncaughtException', function (err) { console.log('Caught exception: ' + err); }); 

Modificare:

 var async_function = function(val, callback){ process.nextTick(function(){ callback(val); }); }; 

La funzione precedente quando chiamata come

 async_function(42, function(val) { console.log(val) }); console.log(43); 

Stamperà 42 alla console in modo asincrono. In particolare process.nextTick si triggers dopo che l’attuale eventloop callstack è vuoto. Lo stack di chiamate è vuoto dopo l’ async_function e async_function console.log(43) . Quindi stampiamo 43 seguiti da 42.

Probabilmente dovresti leggere qualcosa sul ciclo degli eventi.

Basta passare per le callback non è abbastanza. Ad esempio, devi usare settimer per rendere la funzione asincrona.

Esempi: funzioni non asincrone:

 function a() { var a = 0; for(i=0; i<10000000; i++) { a++; }; b(); }; function b() { var a = 0; for(i=0; i<10000000; i++) { a++; }; c(); }; function c() { for(i=0; i<10000000; i++) { }; console.log("async finished!"); }; a(); console.log("This should be good"); 

Se corri sopra l'esempio, questo dovrebbe essere buono, dovrà aspettare fino a quando quelle funzioni finiranno di funzionare.

Funzioni pseudo multithread (async):

 function a() { setTimeout ( function() { var a = 0; for(i=0; i<10000000; i++) { a++; }; b(); }, 0); }; function b() { setTimeout ( function() { var a = 0; for(i=0; i<10000000; i++) { a++; }; c(); }, 0); }; function c() { setTimeout ( function() { for(i=0; i<10000000; i++) { }; console.log("async finished!"); }, 0); }; a(); console.log("This should be good"); 

Questo sarà davvero asincrono. Questo dovrebbe essere buono sarà scritto prima della fine asincrona.

Dovresti vedere questo: Episodio 19 dei Node Tuts – Pattern di iteratura asincrona

Dovrebbe rispondere alle tue domande.

Prova questo, funziona sia per il nodo che per il browser.

 isNode = (typeof exports !== 'undefined') && (typeof module !== 'undefined') && (typeof module.exports !== 'undefined') && (typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false, asyncIt = (isNode ? function (func) { process.nextTick(function () { func(); }); } : function (func) { setTimeout(func, 5); }); 

Se SAPETE che una funzione restituisce una promise, suggerisco di utilizzare le nuove funzionalità asincrone / attendi in JavaScript. Fa sembrare la syntax sincrona ma funziona in modo asincrono. Quando aggiungi la parola chiave async a una funzione, ti consente di await promesse in questo ambito:

 async function ace() { var r = await new Promise((resolve, reject) => { resolve(true) }); console.log(r); // true } 

se una funzione non restituisce una promise, ti consiglio di inserirla in una nuova promise da te definita, quindi risolvere i dati che desideri:

 function ajax_call(url, method) { return new Promise((resolve, reject) => { fetch(url, { method }) .then(resp => resp.json()) .then(json => { resolve(json); }) }); } async function your_function() { var json = await ajax_call('www.api-example.com/some_data', 'GET'); console.log(json); // { status: 200, data: ... } } 

Bottom line: sfruttare il potere di Promises.