Asincrono get l'arrays generato sulla function e passarlo dalla casella (Risolto)

Problema risolto su questo argomento

con questo sotto codice posso generare una matrix semplice come jsonArray nella function checkUserMobileNumberAsEwallet , ma non posso farlo fuori per inviarlo all'interno del client,

con socket.emit('syncContacts', accountNumbers) ottengo [] risultato su accountNumbers , ma in if (success) { arrays di dichiarazione riuscito creato e spinto in accountNumbers arrays

 socket.on('syncContacts', function (data) { var accountNumbers = []; for (var i = 0; i < data.length; i++) { checkUserMobileNumberAsEwallet(data[i].mobileNumber, function (success) { if (success) { accountNumbers.push({ewalletNumber: this.mobileNumber}); console.log(accountNumbers); } }.bind({mobileNumber: data[i].mobileNumber})); } console.log(accountNumbers); socket.emit('syncContacts', accountNumbers); }); function checkUserMobileNumberAsEwallet(mobileNumber, callback) { var mobileNumber = mobileNumber.substr(1, mobileNumber.length); var query = "SELECT id FROM userEwallets WHERE ewalletNumber LIKE '%" + mobileNumber + "'"; connection.query(query, function (err, results) { if (err) return callback(false); if (results.length === 0) return callback(false); else { return callback(true); } }); } 

Aggiornato dopo aver postato i commenti:

 socket.on('syncContacts', function (data) { //console.log(accountNumbers); //socket.emit('syncContacts', accountNumbers); async.parallel( [ function (callback) { var accountNumbers = []; for (var i = 0; i < data.length; i++) { checkUserMobileNumberAsEwallet(data[i].mobileNumber, function (success) { if (success) { accountNumbers.push({ewalletNumber: this.mobileNumber}); console.log(accountNumbers); } }.bind({mobileNumber: data[i].mobileNumber})); } callback(success, accountNumbers); } ], function (success, results) { console.log("results " + results.toString()); socket.emit('syncContacts', results); }); }); function checkUserMobileNumberAsEwallet(mobileNumber, callback) { var mobileNumber = mobileNumber.substr(1, mobileNumber.length); var query = "SELECT id FROM userEwallets WHERE ewalletNumber LIKE '%" + mobileNumber + "'"; connection.query(query, function (err, results) { if (err) return callback(false); if (results.length === 0) return callback(false); else { return callback(true); } }); } 

Sulla base del nostro codice, sembra che checkUserMobileNumberAsEwallet sia un evento asincrono, che accetta una function di richiamata. Ciò significherebbe che il for-loop avrebbe eseguito, che avrebbe messo in coda le esecuzioni per controllare checkUserMobileNumberAsEwallet . Subito dopo l'esecuzione del for-loop, console.log eseguirebbe correttamente l' accountNumbers arrays accountNumbers e emettere l'evento attraverso la presa. Quindi le funzioni di richiamata ad each esecuzione di checkUserMobileNumberAsEwallet inizieranno ad eseguire e registrare l'arrays accountNumbers che ora dispone di dati.

Questo può essere risolto in alcuni modi, ma probabilmente il più semplice e leggibile sarebbe quello di creare Promesse e agire sulle Promesse quando si risolvono. Personalmente mi piace la biblioteca di promise "quando", ma molte biblioteche potrebbero aiutare a risolvere questo problema. https://github.com/cujojs/when/blob/master/docs/api.md#whensettle

Il problema è che non hai alcun controllo su quando il codice all'interno della callback viene eseguito e finisce di eseguire dopo aver già chiamato socket.emit .

Puoi a) utilizzare un aggregatore asincrono per call una callback per each numero di cellulare riuscito e quindi, quando tutti finiscono, call la chiamata socket.emit oppure b) fare qualcosa di simile a quello che ho fatto di seguito. Modificare la function checkUserMobileNumberAsEwallet per accettare e verificare una matrix di numbers mobili e passare i numbers di successo alla function di richiamata

Provare quanto segue:

 socket.on('syncContacts', function (data) { var accountNumbers = []; var mobileNumbers = []; for (var i = 0; i < data.length; i++) { mobileNumbers.push(data[i].mobileNumber); } checkUserMobileNumberAsEwallet(mobileNumbers, function (successfulNumbers) { if (successfulNumbers.length > 0) { for (var i = 0; i < successfulNumbers.length; i++) { accountNumbers.push({ewalletNumber: successfulNumbers[i]}); } socket.emit('syncContacts', accountNumbers); } }.bind({mobileNumbers: mobileNumbers})); });