多个异步mongoose调用完成后执行某些操作

时间:2018-02-13 15:06:28

标签: javascript node.js mongodb asynchronous mongoose

我有一个函数可以在几个不同的文档中查找数据,将每个文档中的一些日期添加到对象中,并使用来自不同文档的组合数据返回该对象。唯一的问题是在完成任何事务之前返回对象。我搜索了很多,我能找到的唯一解决方案是Stack Overflow,但是从2012年开始....必须有一些“更新”更好的方法吗? 最好不要安装更多npm内容。

这是我的功能

function getPreviousEventCard(event, callback) {
    const card = {};
    card.dateStart = event.dateStart;
    card.dateEnd = event.dateEnd;
    card.userID = event.userID;
    card.adminID = event.adminID;

    // 1st async call
    Profile.getFullName(event.userID, (err, name) => {
        if (err) return callback(err, null);
        card.bsName = name.fullName;
    });

    // 2nd async call
    Profile.getProfileByUserId(event.parentID, (err, profile) => {
        if (err) return callback(err, null);
        card.parentName = profile.fullName;
        card.address = `${profile.address} ${profile.zip}`
    });

    // somehow wait until both(all) async calls are done and then:
    return callback(null, card);
}

btw,'Profile'是一个mongoose模式,get方法使用findOne()方法。

我试图嵌套函数并将返回回调作为最内层函数,但是由于某种原因它永远不会被返回。

1 个答案:

答案 0 :(得分:1)

如果您使用的是NodeJS v8或更高版本,我会promisify这些功能:

const getFullName = promisify(Profile.getFullName);
const getProfileByUserId = promisify(Profile.getProfileByUserId);

...然后使用Promise.all

function getPreviousEventCard(event, callback) {
    Promise.all([
        // 1st async call
        getFullName(event.userID),
        // 2nd async call
        getProfileByUserId(event.parentID)
     ])
    .then(([name, profile]) => {
        const card = {
            dateStart: event.dateStart,
            dateEnd: event.dateEnd,
            userID: event.userID,
            adminID: event.adminID,
            bsName: name.fullName,
            parentName: profile.fullName,
            address: `${profile.address} ${profile.zip}`;
        };
        callback(null, card);
    })
    .catch(err => callback(err);
}

或者更好的是,让getPreviousEventCard返回一个承诺:

function getPreviousEventCard(event) {
    return Promise.all([
        // 1st async call
        getFullName(event.userID),
        // 2nd async call
        getProfileByUserId(event.parentID)
     ])
    .then(([name, profile]) => {
        return {
            dateStart: event.dateStart,
            dateEnd: event.dateEnd,
            userID: event.userID,
            adminID: event.adminID,
            bsName: name.fullName,
            parentName: profile.fullName,
            address: `${profile.address} ${profile.zip}`;
        };
    });
}
  

最好不要安装更多npm东西

如果 希望安装更多npm内容,那么会有一个npm模块,它将使用声明性描述来宣传整个API(而不是按功能运行) API函数:https://www.npmjs.com/package/promisify