簡體   English   中英

基於上一個調用的響應進行異步調用,避免了回調地獄

[英]Async call based on a response from a previous call, avoiding callback hell

因此,我通常使用.then鏈處理異步函數。 但這一次並不能解決。 就是這種情況。

return Promise.all([
    Banner.findOne(),
    event.findOne({
        status: true
    }),
    Account.find({
        accType: 'employer'
    })
        .then(([banner, event, account]) => {
            res.render('index', {
                title: 'Web Project Studio',
                user: req.user,
                banner: banner,
                event: event,
                employer: account
            });
        }).catch(e => {
        console.error(e);
    })
]);

因此,這奏效了,一切都很棒。 但是現在我決定改變選擇活動event 我正在調用一個名為generalInfo的集合,並從那里獲取當前事件的ID。 這是我到目前為止的內容:

return Promise.all([
    Banner.findOne(),
    GeneralInfo.findOne(),
    Account.find({
        accType: 'employer'
    })
]).then(([banner, generalInfo, account]) => {
        Event.findById(generalInfo.activeEventId).then(r => {
            console.log('test');
            var event = r;
            res.render('index', {
                title: 'Web Project Studio',
                user: req.user,
                banner: banner,
                event: event,
                employer: account
            });
        }).catch(e => console.log(e));
    }
}).catch(e => {
    console.error(e);
})

但是這段代碼看起來像是一個回調地獄。

我也嘗試過這樣的事情:

var banner = await Banner.findOne().catch(e => console.log(e));
var currentEvent = await GeneralInfo.findOne().catch(e => console.log(e));
currentEvent.then(async r => {
    var event = await Event.findOneById(r.activeEventId).catch(e => console.log(e));
}).catch(e => console.log(e));

它還沒有完成,但是顯示了我的思維方式。 但同樣,沒有運氣。

所以,我怎么能相處異步無鏈接.then下去嗎? 我需要將所有返回的對象傳遞給render函數。

您可以嵌套得更早,這也具有重疊更多的優勢(請參閱***注釋):

return Promise.all([
    Banner.findOne(),
    GeneralInfo.findOne()
        .then(generalInfo => Event.findById(generalInfo.activeEventId)), // ***
    Account.find({
        accType: 'employer'
    })
}).then(([banner, event, account]) => {
    res.render('index', {
        title: 'Web Project Studio',
        user: req.user,
        banner: banner,
        event: event,
        employer: account
    });
}).catch(e => {
    console.error(e);
});

如果您經常執行generalInfo => event事情,則可以將其包裝在實用程序函數中。

或者,如果它們不應該那樣重疊,則可以通過添加另一個then來最小化嵌套:

return Promise.all([
    Banner.findOne(),
    GeneralInfo.findOne(),
    Account.find({
        accType: 'employer'
    })
]).then(([banner, generalInfo, account]) => {
    return Event.findById(generalInfo.activeEventId).then(event => { // ***
        return [banner, event, account];                             // ***
    });                                                              // ***
}).then(([banner, event, account]) => {
    res.render('index', {
        title: 'Web Project Studio',
        user: req.user,
        banner: banner,
        event: event,
        employer: account
    });
}).catch(e => {
    console.error(e);
})

這應該工作。

return Promise.all([
  Banner.findOne(),
  GeneralInfo.findOne(),
  Account.find({
    accType: 'employer'
  })
]).then(async ([banner, generalInfo, account]) => {
    res.render('index', {
      title: 'Web Project Studio',
      user: req.user,
      banner: banner,
      event: await Event.findById(generalInfo.activeEventId),
      employer: account
    });
}).catch(e => {
    console.error(e);
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM