3
votes

nodejs écrit des fonctions synchrones, par exemple fs.readFileSync

Je souhaite créer des fonctions qui récupèrent les données de la base de données, par exemple executeQuery (sql) . Mais je ne veux aucune promesse retournée par cette fonction ou je veux passer une fonction de rappel. Je veux juste renvoyer le résultat de la requête.

Par exemple:

var rows = executeQuery('SELECT * FROM table');
console.log('database query completed:', rows);

Je sais que ce n'est pas ainsi que fonctionne javascript. J'ai également traversé un certain nombre de questions de stackoverflow qui voulaient également cette chose. Mais tout le monde dit qu'il n'y a aucun moyen de le faire.

Voici ma question si ce n'est pas possible, alors comment fonctionnent des fonctions comme fs.readFileSync () . Ces fonctions ne nécessitent aucun rappel et ne renvoient aucune promesse. Ils font simplement ce pour quoi ils sont définis.


1 commentaires

Vous pouvez créer votre propre package mysql en utilisant npmjs.com/package/sync -socket


4 Réponses :


-1
votes

Vous pouvez utiliser async / wait. Cela vous donnerait à peu près la même syntaxe que readFileSync - il ne s'agit pas de chaînes de promesse ni de rappels.

var rows = await executeQuery('SELECT * FROM table')
console.log('database query completed:', rows) // this now works

Il vous suffirait de l'envelopper dans la fonction async.

Simplement pour éviter toute confusion. La fonction est toujours asynchrone, c'est juste du sucre de syntaxe qui facilite la lecture du code.


2 commentaires

Le mot clé await ne peut être utilisé que dans des fonctions déclarées asynchrones. C'est pourquoi je veux savoir comment fonctionne fs.readFileSync () .


Cela fonctionne en bloquant la boucle d'événements dans JavasScript: Vérifiez: nodejs.org/en/docs/guides/event-loop-timers-and-nexttick et youtube.com/watch?v=8aGhZQkoFbQ Notez simplement que la philosophie de conception de nodeJS est de ne pas le bloquer. Donc, vous iriez contre ce modèle de conception.



-2
votes

La synchronisation est synchrone et bloque l'exécution jusqu'à ce qu'elle soit terminée. Les méthodes Sync de fs renvoient leurs résultats sous forme de valeurs de retour.

Les autres méthodes fs non sync sont asynchrones et retournent immédiatement pendant qu'elles fonctionnent en arrière-plan. Vous passez une fonction de rappel qui est appelée à la fin.

Les promesses sont un peu un cauchemar lorsque vous commencez à utiliser Javascript, mais parce que Javascript n'a qu'un seul thread, elles font partie de la beauté de Javascript une fois que vous vous y êtes habitué. Si vous utilisez les fonctions de synchronisation, vous bloquez le thread, ce qui n'est généralement pas une bonne idée, surtout si vous n'utilisez pas de nœuds de calcul.

J'ai écrit un article sur les promesses de tête à tête si vous souhaitez le vérifier ici

Pourquoi Async renvoie-t-il toujours une promesse?



1
votes

Mise à jour: comme @Paulpro l'a dit dans les commentaires, cette réponse ci-dessous ne fonctionnerait jamais, car le code sera bloqué en boucle infinie. donc vous feriez mieux de suivre un Promises


Je conseille comme @ happy-machine & @bergur, il vaut mieux utiliser Promises. mais si vous voulez savoir comment fonctionne fs.readFileSync () , alors allez lire code du module fs dans le code source de nodejs .

Vous constaterez qu'il fait un do {} while () code > et vous pouvez faire la même chose pour synchroniser votre code asynchrone comme ceci

var rows;
executeQuery('SELECT * FROM table').then(
  promiseResponse => {
   rows = promiseResponse
  }
)
do {
  // nothing
} while(!rows) // rows is undefined
console.log('database query completed:', rows);


4 commentaires

Cela a une boucle infinie qui ne modifie pas les lignes , il ne peut jamais atteindre la ligne console.log.


J'ai modifié la réponse, la fonction à une fonction de flèche, qui changera les lignes


La fonction flèche ne s'exécute jamais car une boucle infinie est en cours d'exécution.


Essayez simplement var rows; setTimeout (_ => {rows = true;}, 100); faire {} while (! lignes); console.log ('jamais atteint'); pour voir ce que je veux dire.



0
votes

fs.readFileSync () peut être synchrone car il ne fonctionne qu'avec votre système de fichiers local, ce qui peut être une opération rapide. Si votre base de données est locale, elle pourrait également être écrite de manière synchrone. Cependant, si votre base de données est sur le net, executeQuery devra envoyer une requête http et attendre une réponse qui peut prendre beaucoup de temps et pourrait ne pas être possible de faire de manière synchrone en raison de ce qui suit:

Remarque: à partir de Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), les requêtes synchrones sur le thread principal sont devenues obsolètes en raison des effets négatifs sur l'expérience utilisateur.


0 commentaires