javascript - problème de nœud asynchrone
大家讲道理
大家讲道理 2017-05-16 13:23:54
0
6
343

Je souhaite que le rappel soit exécuté après findById, mais il ne peut pas être placé dans son rappel, sinon il sera exécuté plusieurs fois. Que dois-je faire?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

répondre à tous(6)
漂亮男人

Le logiciel est une industrie de services, vous devez avoir une conscience du service... Il n'y a aucun problème avec la carte du code, vous pouvez le voir clairement, mais si le répondant veut changer votre code, vous devez le retaper...

Je vois que vous avez déjà utilisé la syntaxe es6, la bonne solution doit donc être Promise, qui peut être encapsulée dans Promies par vous-même

exports.findList = function(findObj, callback) {
    Info.find(findObj, function(err, info) {
        const promises = info.map(f => new Promise((resolve, reject) => {
            f.image = f.images.split(",")[0];
            User.findById(f.author_id, function(error, user) {
                if (error) {
                    reject(error);
                    return;
                }

                f.author_name = user.name;
                f.authro_avatar = user.avatar;
                resolve(f);
            });
        }));

        Promise.all(promises)
            .then(function(values) {
                // 成功的时候,这个 values 是所有 info 对象,
                // 作为一个数组返回出来,而不是某一个
                callback(null, values);
            })
            .catch(function(error) {
                // 注意这里 error 是第一个失败 error
                // 不是所有的 error 
                callback(error);
            });
    });
};

Bien sûr, vous pouvez également utiliser les fonctions d'outils fournies par Bluebird pour encapsuler Promise

Il convient de noter que vous exécutez ici plusieurs appels asynchrones, donc si vous souhaitez les renvoyer ensemble, il doit y avoir plusieurs résultats. Faites donc attention au rappel dans then() après Promise.all. Promise.all 后面 then() 中的回调。

如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在 findById

Si vous souhaitez utiliser es5, il est recommandé d'écrire es6 puis d'utiliser Babel. Cependant, Node 7.6+ prend déjà en charge certaines fonctionnalités d'es2017, vous n'avez donc pas réellement à vous soucier de ce problème. Si vous en avez vraiment besoin, utilisez la méthode de comptage dans le rappel findById pour compter les mouvements d'agrandissement (appelez le rappel). 🎜
我想大声告诉你

Option 1

Utilisez async/await. Cela vous permet d'utiliser User.findById de manière synchrone. async/await。这样就可以按照同步方式使用 User.findById

方案二

在循环中把 User.findById 加入一个数组,然后用 Promise.allcallback 写在 Promise.all().then() 中。

方案三

使用一个状态变量,每次检查一下,满足条件再执行 callback

🎜Option 2🎜🎜 🎜Ajoutez User.findById à un tableau dans la boucle, puis utilisez Promise.all et callback pour écrire dans Promise.all () dans .then(). 🎜 🎜🎜Option 3🎜🎜 🎜Utilisez une variable d'état, vérifiez-la à chaque fois, puis exécutez callback si les conditions sont remplies. Méthode laide, ne l'utilisez pas. 🎜
Peter_Zhu

Définissez un paramètre, exécutez le réglage, puis saisissez le jugement de rappel à chaque fois..

某草草

Pour l'enfer des rappels, veuillez utiliser Promise ou des bibliothèques similaires.

巴扎黑
exports.findList=function (findObj,callback) {
    Info.find(findObj,function (err,info) {
        for(let i in info){
            info[i].image=info[i].images.split(',')[0];
            User.findById(info[i].author_id,function (error,user) {
                info[i].author_name=user.name;
                info[i].author_avatar=user.avatar;
                if(i==info.length-1){
                    callback(err,info);
                }
            })
        }
    })
}

Ma solution est un peu faible. . ?

迷茫

Le deuxième étage est correct, utilisez la promesse pour le résoudre.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal