javascript - isu async nod
大家讲道理
大家讲道理 2017-05-16 13:23:54
0
6
345

Saya mahu panggilan balik dilaksanakan selepas findById, tetapi ia tidak boleh diletakkan dalam panggilan baliknya, jika tidak, ia akan dilaksanakan beberapa kali. Apa patut saya buat?

大家讲道理
大家讲道理

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

membalas semua(6)
漂亮男人

Software adalah industri perkhidmatan, anda mesti ada kesedaran perkhidmatan... Tiada masalah dengan peta kod, anda boleh melihatnya dengan jelas, tetapi jika responden ingin menukar kod anda, anda perlu menaipnya semula...

Saya nampak anda telah pun menggunakan sintaks es6, jadi penyelesaian yang betul mestilah Promise, yang boleh dimasukkan ke dalam Promies sendiri

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

Sudah tentu, anda juga boleh menggunakan fungsi alat yang disediakan oleh Bluebird untuk merangkum Promise

Perlu diingat bahawa anda menjalankan berbilang panggilan tak segerak di sini, jadi jika anda ingin mengembalikannya bersama-sama, mesti terdapat berbilang hasil. Oleh itu, beri perhatian kepada panggilan balik dalam then() selepas Promise.all. Promise.all 后面 then() 中的回调。

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

Jika anda ingin menggunakan es5, disyorkan anda menulis es6 dan kemudian menggunakan Babel. Walau bagaimanapun, Node 7.6+ sudah menyokong beberapa ciri es2017, jadi anda sebenarnya tidak perlu risau tentang isu ini. Jika anda benar-benar memerlukannya, gunakan kaedah mengira dalam panggilan balik findById untuk mengira pergerakan pembesaran (panggil panggilan balik). 🎜
我想大声告诉你

Pilihan 1

Gunakan async/wait. Ini membolehkan anda menggunakan User.findById secara serentak. async/await。这样就可以按照同步方式使用 User.findById

方案二

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

方案三

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

🎜Pilihan 2🎜🎜 🎜Tambah User.findById pada tatasusunan dalam gelung, dan kemudian gunakan Promise.all dan panggilan balik untuk menulis dalam Promise.all () dalam .then(). 🎜 🎜🎜Pilihan 3🎜🎜 🎜Gunakan pembolehubah keadaan, semak setiap kali, dan kemudian laksanakan panggilan balik jika syarat dipenuhi. Kaedah hodoh, jangan gunakannya. 🎜
Peter_Zhu

Tetapkan parameter, laksanakan tetapan, dan kemudian masukkan penghakiman panggil balik setiap kali..

某草草

Untuk panggilan balik neraka, sila gunakan Janji atau perpustakaan yang serupa.

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

Penyelesaian saya agak rendah. . ?

迷茫

Tingkat dua betul, gunakan janji untuk menyelesaikannya.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan