web-dev-qa-db-fra.com

Comment puis-je faire cet appel pour demander dans nodejs synchrone?

J'ai une fonction dans mon application nodejs appelée get_source_at. Il prend un uri comme argument et son but est de renvoyer le code source à partir de cet uri. Mon problème est que je ne sais pas comment faire la demande d'appel de manière synchrone, plutôt que de lui donner cette fonction de rappel. Je veux le contrôle du flux s’arrête pendant quelques secondes pour charger l’URI. Comment puis-je atteindre cet objectif?

function get_source_at(uri){
    var source;
    request({ uri:uri}, function (error, response, body) {
        console.log(body);
    });
    return source;
}

De plus, j'ai lu des articles sur les "événements" et sur la façon dont les nœuds sont "événementés" et je devrais respecter cela lors de l'écriture de mon code. Je suis heureux de le faire, mais je dois avoir un moyen de m'assurer que j'ai le code source d'un uri avant de continuer le flux de contrôle de mon application - donc si ce n'est pas en rendant la fonction synchrone, comment faire ?

18
Trindaz

Vous devez éviter les requêtes synchrones. Si vous voulez quelque chose comme un flux de contrôle synchrone, vous pouvez utiliser async .

async.waterfall([
    function(callback){
        data = get_source_at(uri);
        callback(null, data);
    },
    function(data,callback){
        process(data, callback);
    },
], function (err,result) {
    console.log(result)
});

process est promis d'être exécuté après le retour deget_source_at.

13
Lai Yu-Hsuan

Vous pouvez avec deasync :

function get_source_at(uri){
    var source;
    request({ uri:uri}, function (error, response, body) {
        source = body;
        console.log(body);
    });
    while(source === undefined) {
      require('deasync').runLoopOnce();
    }
    return source;
}
16
abbr

Avoir une fonction de blocage simple est un avantage considérable pour le développement interactif! La fonction sync (définie ci-dessous) peut synchroniser n'importe quelle promesse, réduisant considérablement le nombre de syntaxes nécessaires pour jouer avec une API et l'apprendre. Par exemple, voici comment l’utiliser avec la bibliothèque puppeteer pour Chrome sans tête:

var browser = sync(puppeteer.connect({ browserWSEndpoint: "ws://some-endpoint"}));
var pages = sync(browser.pages())
pages.length
1
var page = pages[0]
sync(page.goto('https://duckduckgo.com', {waitUntil: 'networkidle2'}))
sync(page.pdf({path: 'webpage.pdf', format: 'A4'}))

La meilleure partie est que chacune de ces lignes peut être modifiée jusqu'à ce qu'elle fasse ce que vous voulez, sans avoir à réexécuter ou à retaper toutes les lignes précédentes à chaque fois que vous souhaitez la tester. Cela fonctionne car vous avez un accès direct aux variables browser et pages à partir du niveau supérieur.

Voici comment ça fonctionne:

const deasync = require("deasync");
const sync = deasync((promise, callback) => promise.then(result) => callback(null, result)));

Il utilise le paquet deasync mentionné dans d'autres réponses. deasync crée une application partielle à la fonction anonyme, qui ajoute callback comme dernier argument et reste bloquée jusqu'à ce que callback ait été appelé. callback reçoit la condition d'erreur en tant que premier argument (le cas échéant) et le résultat en tant que second (le cas échéant).

2
jpaugh

Je dois avoir un moyen de m'assurer que j'ai le code source d'un uri avant de continuer le flux de contrôle de mon application - donc si ce n'est pas en rendant la fonction synchrone, comment peut-on le faire?

Étant donné ce point d’entrée dans votre application:

function app(body) {
    // Doing lots of rad stuff
}

Vous démarrez en récupérant le corps:

request({ uri: uri }, function (error, response, body) {
    if(err) return console.error(err);

    // Start application
    app(body);
}

C’est quelque chose auquel vous devrez vous habituer lors de la programmation de node.js (et de javascript en général). Il existe des modules de flux de contrôle comme async (que je recommande également), mais vous devez vous habituer au style de passage continuation, comme on l'appelle.

Ok, tout d’abord, pour garder ce code asynchrone, vous pouvez simplement placer le code correspondant dans le rappel de la fonction de requête, ce qui signifie qu’elle sera exécutée une fois la requête terminée, sans toutefois empêcher le processeur de gérer d’autres tâches dans votre application. Si vous en avez besoin plusieurs fois, je vous conseillerais de vérifier Requête synchrone dans Node.js , qui décrit diverses méthodes permettant d’optimiser cette opération et d’examiner diverses bibliothèques de flux de contrôle.

0
David Mulder