Javascript – Knotenasynchronitätsproblem
大家讲道理
大家讲道理 2017-05-16 13:23:54
0
6
344

Ich möchte, dass der Rückruf nach findById ausgeführt wird, aber er kann nicht in seinen Rückruf eingefügt werden, da er sonst mehrmals ausgeführt wird. Was soll ich machen?

大家讲道理
大家讲道理

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

Antworte allen(6)
漂亮男人

软件是服务行业,要有服务意识……代码贴图没问题,可以看得很清晰,但是如果回答者想改你的代码,还得重新敲一遍…………

我看你已经用了 es6 的语法,所以正解肯定是 Promise,可以自己封装成 Promies

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);
            });
    });
};

当然也可以用 Bluebird 提供的工具函数来封装 Promise

需要注意的是你这里运行了好多个异步调用,所以要一起返回的话,肯定也是好多个结果。所以注意 Promise.all 后面 then() 中的回调。

如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在 findById 回调中记数的办法,记满放大招(调用 callback)。

我想大声告诉你

方案一

使用 async/await。这样就可以按照同步方式使用 User.findById

方案二

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

方案三

使用一个状态变量,每次检查一下,满足条件再执行 callback。丑陋的方法,不要用。

Peter_Zhu

设置个参数,执行完设置下,以后每次进入回调判断下 ..

某草草

对于callback地狱,请使用Promise 或者类似类库。

巴扎黑
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);
                }
            })
        }
    })
}

我的解决方法,有点low。。?

迷茫

二楼说得对,用promise解决。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage