À l'aide de Promesses avec fs.readFile dans une boucle
J'essaie de comprendre pourquoi la ci-dessous promesse configurations ne fonctionnent pas.
(Note: j'ai déjà résolu ce problème avec async.carte. Mais je voudrais savoir pourquoi mes tentatives ci-dessous ne fonctionne pas.)
Le bon comportement devrait être: bFunc doit exécuter autant de fois que nécessaire pour fs lire tous les fichiers d'image (bFunc ci-dessous s'exécute deux fois) et puis cFunc console affiche "Fin".
Merci!
Tentative 1: Il court et s'arrête à cFunc().
var fs = require('fs');
bFunc(0)
.then(function(){ cFunc() }) //cFunc() doesn't run
function bFunc(i){
return new Promise(function(resolve,reject){
var imgPath = __dirname + "/image1" + i + ".png";
fs.readFile(imgPath, function(err, imagebuffer){
if (err) throw err;
console.log(i)
if (i<1) {
i++;
return bFunc(i);
} else {
resolve();
};
});
})
}
function cFunc(){
console.log("End");
}
Tentative 2:
Dans ce cas, j'ai utilisé une boucle for mais il s'exécute hors de l'ordre. Console imprime: Fin, bFunc fait, bFunc fait
var fs = require('fs');
bFunc()
.then(function(){ cFunc() })
function bFunc(){
return new Promise(function(resolve,reject){
function read(filepath) {
fs.readFile(filepath, function(err, imagebuffer){
if (err) throw err;
console.log("bFunc done")
});
}
for (var i=0; i<2; i++){
var imgPath = __dirname + "/image1" + i + ".png";
read(imgPath);
};
resolve()
});
}
function cFunc(){
console.log("End");
}
Merci pour l'aide à l'avance!
- Dans la tentative de 1, quel est votre gestionnaire d'erreur pour
bFunc
? Si une erreur est levée, vous ne saurez jamais ce sujet avec votre code actuel. - Quel est le but de ce code? Veuillez décrire le problème que vous essayez de résoudre par des mots plutôt que de simplement nous montrer le code qui ne fait pas ce que vous voulez. Il y a beaucoup de choses de mal avec votre code donc je préfère commencer de comprendre le problème à résoudre que d'essayer de retravailler toutes les choses de mal avec votre code sans en connaître la fin réelle de l'objectif.
- il ne jette pas une erreur à la bFunc! Mais je suppose que je devrais mettre une capture à la fin de la chaîne.
- J'ai enlevé tout le détail de ce code et juste à gauche de la structure, de le simplifier. Le problème est le même, mais si cela peut aider, j'ai été en utilisant Microsoft Projet d'Oxford pour la détection de visage et puis, à chaque "."je augmenter la photo avec des lunettes, des chapeaux, etc. Je peux partager le code source avec vous. Merci.
- Eh bien, pensez-y de notre point de vue. - Vous nous donner deux blocs de code qui ne fonctionnent pas et nous demander comment les corriger. Mais, vous n'avez jamais vraiment décrire ce qu'ils sont censés faire (ce que le comportement correct est). Sommes-nous censés deviner à partir du dysfonctionnement code ce le bon comportement? Veuillez décrire le souhaité et le bon comportement que vous souhaitez à partir de bloc de code.
- Je vois votre point de vue et j'ai édité le post: Le bon comportement devrait être: bFunc doit exécuter autant de fois que nécessaire pour fs lire tous les fichiers d'image (bFunc s'exécute deux fois dans ce cas) et puis cFunc console affiche "Fin".
- Êtes-vous essayer d'appeler fs.readFile() plusieurs fois pour lire les fichiers en parallèle? Jetez un oeil à codendeavor.com/...
- J'aime ceci réponse
Vous devez vous connecter pour publier un commentaire.
Donc, quand vous avez plusieurs opérations asynchrones afin de coordonner, d'une certaine façon, j'ai tout de suite envie d'aller à des promesses. Et, la meilleure façon d'utiliser les promesses de coordonner un certain nombre d'opérations asynchrones est de faire de chaque opération asynchrone retour d'une promesse. Le plus bas niveau de l'opération asynchrone vous montrer, c'est
fs.readFile()
. Depuis que j'utilise le Bluebird promesse de la bibliothèque, il a une fonction de "promisifying" un module entier vaut la peine de async fonctions.Cela permettra de créer de nouvelles méthodes parallèles sur le
fs
objet avec un "Async" suffixe de retour des promesses plutôt que d'utiliser directement les rappels. Donc, il y aura unfs.readFileAsync()
qui retourne une promesse. Vous pouvez en lire plus à propos de Bluebird est promisification ici.Donc, maintenant vous pouvez faire une fonction qui récupère une image assez simplement et retourne une promesse dont la valeur est les données de l'image:
Puis, dans votre code, il semble que vous voulez faire
bFunc()
être une fonction qui lit trois de ces images et des appelscFunc()
quand elles sont faites. Vous pouvez le faire comme ceci:Si vous ne souhaitez pas utiliser Bluebird, vous pouvez effectuer manuellement une promesse version de
fs.readFile()
comme ceci:Ou, dans les versions modernes de la node.js, vous pouvez utiliser
util.promisify()
de faire un promisified version d'une fonction qui suit la node.js async convention d'appel:Bien, vous allez trouver rapidement une fois que vous commencez à utiliser des promesses, vous voulez les utiliser pour toutes les opérations asynchrones de sorte que vous serez "promisifying" beaucoup de choses et avoir une bibliothèque ou au moins une fonction générique qui le fera pour vous permettra d'économiser beaucoup de temps.
En même les nouvelles versions de node.js (version 10.0+), vous pouvez utiliser la version intégrée de la
fs
bibliothèque qui prend en charge les promesses:Promise.promisifyAll
au lieu dePromise.promisify
const {promisify} = require("util"); const fs = require("fs"); const readFile = promisify(fs.readFile);
util.promisify()
comme une option dans les versions plus récentes de node.js est déjà dans ma réponse.Votre code devrait ressembler à ceci:
D'utilisation avec une seule image:
Utilisation avec de multiples images:
À promisify fonction des moyens à prendre une fonction d'asynchrone avec rappel de la sémantique et de tirer une nouvelle fonction avec la promesse de la sémantique.
Il peut être fait manuellement, comme indiqué ci-dessus, ou – de préférence – automatiquement. Entre autres, le Bluebird promesse de la bibliothèque dispose d'un helper pour cela, voir http://bluebirdjs.com/docs/api/promisification.html
Nœud v10 a fs Promesses API
https://nodejs.org/api/fs.html#fs_fs_promises_api
vous pouvez aussi utiliser ce module:
'fs-readfile-promesse"
JS: