2012-10-06 16 views
21

Posso contare sul mapping di nodeID completato ogni volta che viene chiamato DoSomething()?Node.js Array.map() asincrono?

nodeIDs = $.map(nodeIDs, function(n){ 
    return n.match(/\d+$/); 
}); 
doSomething(nodeIDs); 

Ho pensato che tutti i callback in node.js sono asincroni? Ho letto un articolo sulla programmazione generale che callback potrebbe essere sincrono ma non sono sicuro di node.js?

+0

cos'è $ qui? map accetta una funzione di callback da applicare a ciascun membro dell'elenco, non una richiamata quando l'iterazione completa è completa. – chovy

+0

Grazie chovy.Per quanto riguarda $, stavo solo sperimentando il modulo node-jquery e non mi sono preoccupato di modificarlo. – bonchef

risposta

32

JavaScript è anche un linguaggio di programmazione funzionale. Quello che hai qui è una «funzione di ordine superiore», una funzione che prende una funzione come parametro. Le funzioni di ordine superiore sono sincrone (ma vedi nota sotto).

Fonti:

map() è un tipico esempio di una funzione di ordine superiore. Prende una funzione e la applica a tutti gli elementi di un array. La definizione suona molto «funzionale». Questa funzione non è fornita dal nodo. È documentato da MDN Array.prototype.map() e specificato da ECMAScript 5.1.

Per rispondere alla tua domanda: Sì, è chiamato dopo tutti gli elementi sono stati applicati.


Nota: La funzione di ordine superiore è un concetto di programmazione funzionale. JavaScript è funzionale, ma anche profondamente inserito nella praticità dell'esecuzione di codice all'interno di un browser o sul server. Direi che ad esempio setTimeout() non è una funzione di ordine superiore anche se accetta una funzione come parametro perché setTimeout() non è realmente puramente funzionale perché utilizza il tempo. La pura funzionalità è senza tempo. Ad esempio il risultato di map() non dipende dal tempo. E questa è la vera domanda. Se qualcosa non dipende dal tempo, lo si esegue in modo sincrono. Problema risolto.

Grazie a Simon per aver sfidato la definizione della funzione di ordine superiore in JavaScript.

+0

Grazie nalply. Guardare l'implementazione di riferimento di map() aiuta. – bonchef

+0

* Le funzioni di ordine superiore sono sincrone * - davvero? setTimeout è anche una funzione di ordine superiore, ma è asincrona. –

+0

@ SimonA.Eugster Hai un punto. Se si definiscono strettamente funzioni che assumono funzioni come parametri come «ordine superiore», allora le funzioni asincrone sono anche «ordine superiore». Come chiamereste le funzioni sincrone che assumono funzioni come parametri? – nalply

0

Questa funzione è sincrona, altrimenti non è possibile restituire il risultato dell'operazione della mappa.

Eventuali callback che potrebbero richiedere più tempo (principalmente a causa di IO) sono asincroni nei nodejs, a meno che il metodo non sia esplicitamente contrassegnato come sincrono (come ad esempio fs.readFileSync - ma che non usi una richiamata). Probabilmente lo hai confuso in qualche modo.

+0

Grazie ThiefMaster. Capisco la parte delle versioni Sync e Async delle funzioni IO e ho usato entrambi in passato. Per riformulare meglio la mia domanda: dato un segmento di codice, quando non ci sono callback, posso assumere il flusso sincrono. Ma quando ci sono callback, non c'è un modo ovvio per confermare a senso unico o l'altro? Se sono coinvolti IO, probabilmente sono asincroni. Ma nel caso della map() non ero così sicuro - né nodejs né i riferimenti Javascript sembrano specificarlo. Quindi, come posso dire per la prossima funzione di libreria che incontro? – bonchef

+0

I documenti lo dicono. Per esempio. http://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback "rinomina asincrona" – ThiefMaster

11

Sì, .map è sincrono. "Callback" non implica "asincrono".

+1

Grazie Charmander. Intendevo dire "quando si è nel dubbio, si supponga che i callback possano essere chiamati in modo asincrono in un momento diverso". Quindi la vera domanda è (vedi i miei commenti sopra) - In generale, come posso sapere se una determinata funzione di libreria è asincrona o no? – bonchef

+0

Le funzioni del file node.js per esempio sono ben documentate, ma altre, come la mappatura degli array, non riesco a trovare questa particolare informazione. – bonchef

+0

Questo perché non sono forniti dal nodo. Appartengono al runtime V8. V8 implementa ECMAScript. 'Array.map()' è documentato qui: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map. – nalply

3

importare il modulo async di avere un asincrono 'map' metodo

var async = require('async'); 

var arr = ['1','2']; 
async.map(arr, getInfo, function (e, r) { 
    console.log(r); 
}); 

function getInfo(name, callback) { 
    setTimeout(function() { 
    callback(null, name + 'new'); 
    }, 1000); 
}