J'ai essayé de rechercher comment exactement les fonctions asynchrones devraient être écrites. Après beaucoup de recherches dans de nombreux documents, je ne comprends toujours pas.
Comment écrire des fonctions asynchrones pour Node? Comment dois-je implémenter correctement la gestion des événements d'erreur?
Une autre façon de poser ma question serait la suivante: comment interpréter la fonction suivante?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
Aussi, j'ai trouvé cette question sur SO ("Comment créer une fonction asynchrone non bloquante dans node.js? ") intéressant. Je n'ai pas l'impression d'avoir reçu de réponse.
Vous semblez confondre asynchrone IO avec des fonctions asynchrones. Node.js utilise une méthode asynchrone non bloquante IO car non bloquante IO = C’est mieux. La meilleure façon de le comprendre est d’aller regarder des vidéos de Ryan Dahl.
Comment écrire des fonctions asynchrones pour Node?
Il suffit d'écrire des fonctions normales, la seule différence est qu'elles ne sont pas exécutées immédiatement, mais transmises en tant que rappels.
Comment dois-je mettre en œuvre la gestion des événements d'erreur correctement
Généralement, les API vous rappellent avec une erreur comme premier argument. Par exemple
database.query('something', function(err, result) {
if (err) handle(err);
doSomething(result);
});
Est-ce un modèle commun.
Un autre motif commun est on('error')
. Par exemple
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
Edit:
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
La fonction ci-dessus quand appelé comme
async_function(42, function(val) {
console.log(val)
});
console.log(43);
Imprimera 42
Sur la console de manière asynchrone. En particulier, process.nextTick
Se déclenche une fois que la pile d'appels de la boucle d'événements en cours est vide. Cette pile d'appels est vide après l'exécution de async_function
Et console.log(43)
. Nous imprimons donc 43 suivis de 42.
Vous devriez probablement lire un peu sur la boucle d'événement.
Passer des rappels ne suffit pas. Vous devez utiliser settimer par exemple, pour rendre la fonction async.
Exemples: Fonctions non asynchrones:
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");
Si vous allez exécuter l'exemple ci-dessus, cela devrait être bon, il faudra attendre jusqu'à ce que ces fonctions se terminent pour fonctionner.
Fonctions pseudo multithreads (asynchrones):
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");
Celui-ci sera vraiment async. Cela devrait être bon sera écrit avant async fini.
Vous devriez regarder ceci: Épisode 19 de Node Tuts - Modèles d'itérations asynchrones
Cela devrait répondre à vos questions.
Si vous SAVEZ qu'une fonction retourne une promesse, je suggère d'utiliser les nouvelles fonctionnalités async/wait en JavaScript. Cela donne à la syntaxe une apparence synchrone mais fonctionne de manière asynchrone. Lorsque vous ajoutez le mot-clé async
à une fonction, il vous permet de await
promettre dans cette étendue:
async function ace() {
var r = await new Promise((resolve, reject) => {
resolve(true)
});
console.log(r); // true
}
si une fonction ne retourne pas une promesse, je vous recommande de l'envelopper dans une nouvelle promesse que vous définissez, puis résolvez les données souhaitées:
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: ... }
}
En bout de ligne: tirer parti de la puissance des promesses.
Essayez ceci, cela fonctionne pour le noeud et le navigateur.
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);
});
J'ai trop d'heures consacrées à une telle tâche pour node.js. Je suis principalement un gars front-end.
Je trouve cela assez important, car toutes les méthodes de noeud asyncroniennes traitent le rappel, et le transforment en promesse vaut mieux le gérer.
Je veux juste montrer un résultat possible, plus maigre et lisible. En utilisant ECMA-6 avec async, vous pouvez l'écrire comme ceci.
async function getNameFiles (dirname) {
return new Promise((resolve, reject) => {
fs.readdir(dirname, (err, filenames) => {
err !== (undefined || null) ? reject(err) : resolve(filenames)
})
})
}
le (undefined || null)
est pour les scénarios repl (lire la boucle d’impression d’événement), en utilisant également indéfini.