javascript - node async issue
大家讲道理
大家讲道理 2017-05-16 13:23:54
0
6
323

You want the callback to be executed after findById, but it cannot be placed in its callback, otherwise it will be executed multiple times. What should I do?

大家讲道理
大家讲道理

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

reply all(6)
漂亮男人

Software is a service industry, you must have service awareness... There is no problem with the code map, you can see it very clearly, but if the respondent wants to change your code, you have to type it again...

I see that you have already used es6 syntax, so the correct solution must be Promise, which can be encapsulated into Promies by yourself

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

Of course, you can also use the tool functions provided by Bluebird to encapsulate Promise

It should be noted that you are running multiple asynchronous calls here, so if you want to return them together, there must be multiple results. So notice the callback in Promise.all 后面 then().

If you want to use es5, it is recommended that you write es6 and then use Babel. However, Node 7.6+ already supports some features of es2017, so you don’t actually need to worry about this issue. If you really need it, use the method of counting in the findById callback to count up the enlargement moves (call the callback).

我想大声告诉你

Option 1

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

Option 2

Insert User.findById 加入一个数组,然后用 Promise.allcallback 写在 Promise.all().then() in the loop.

Option 3

Use a state variable, check it every time, and then execute it if the conditions are met callback. Ugly method, don't use it.

Peter_Zhu

Set a parameter, execute the setting, and then enter the callback judgment every time..

某草草

For callback hell, please use Promise or similar libraries.

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

My solution is a bit low. . ?

迷茫

The second floor is right, use promise to solve it.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!