web-dev-qa-db-fra.com

Node.js et Express: comment renvoyer une réponse après un fonctionnement asynchrone

Je suis nouveau sur Node.js, donc je continue de me concentrer sur les fonctions asynchrones et les rappels. Mon problème est maintenant de savoir comment retourner une réponse après avoir lu les données d'un fichier dans une opération asynchrone.

Ma compréhension est que l'envoi d'une réponse fonctionne comme ceci (et cela fonctionne pour moi):

app.get('/search', function (req, res) {
    res.send("request received");
});

Cependant, maintenant je veux lire un fichier, effectuer certaines opérations sur les données, puis retourner les résultats dans une réponse. Si les opérations que je voulais effectuer sur les données étaient simples, je pourrais faire quelque chose comme ça - les exécuter en ligne et conserver l'accès à l'objet res car il est toujours à portée.

app.get('/search', function (req, res) {
    fs.readFile("data.txt", function(err, data) {
        result = process(data.toString());
        res.send(result);
    });
});

Cependant, les opérations sur les fichiers que je dois effectuer sont suffisamment longues et compliquées pour que je les sépare dans leur propre fonction dans un fichier séparé. En conséquence, mon code ressemble plus à ceci:

 app.get('/search', function (req, res) {
    searcher.do_search(res.query);
    // ??? Now what ???
});

Je dois appeler res.send pour envoyer le résultat. Cependant, je ne peux pas l'appeler directement dans la fonction ci-dessus, car do_search se termine de manière asynchrone. Et je ne peux pas l'appeler dans le rappel à do_search car l'objet res n'y est pas inclus.

Quelqu'un peut-il m'aider à comprendre la bonne façon de gérer cela dans Node.js?

15
ekl

Pour accéder à une variable dans une fonction différente, lorsqu'il n'y a pas de portée partagée, passez-la comme argument.

Vous pouvez simplement passer res puis accéder à la fois query et send sur la seule variable de la fonction.


À des fins de séparation des préoccupations, vous feriez mieux de passer un rappel à la place.

Ensuite do_search n'a besoin que de savoir comment exécuter une requête, puis exécuter une fonction. Cela le rend plus générique (et donc réutilisable).

searcher.do_search(res.query, function (data) {
    res.send(...);
});

function do_search(query, callback) {
    callback(...);
} 
17
Quentin