最后,函数被多次调用

时间:2018-04-27 12:04:07

标签: node.js es6-promise

我正在尝试编写一系列Promises,但最后一次 .then()被多次调用,我不知道为什么。最后一个 .then()必须运行一次,因为它会调用另一个API,将 result 作为正文传递。

我知道这是多次被调用,因为我正在登录为console.log()。

我的代码出了什么问题?根据我的理解,那么()应该等待承诺返回一些东西。

app.post('/router/join', function(req, res){
    let data = req.body;
    sessions.validate(data)
    .then(result => {
        return {
            authenticated: (result.code === 201)                
        };
    })
    .then(result => {        
        if(result.authenticated){
            return contacts.getContacts(data.tenant_id).then(cs => {
                let json = merge(result, cs.data);            
                return Promise.all(cs.data.items.map(contact => {
                    return messages.getLastMessage(data.tenant_id, contact.item.contact_id, data.hash_id)
                        .then(result => {
                            contact.item.last_message = result.code === 200 && result.data.length > 0 ? result.data[0] : null;
                            return contact;
                        });                    
                })).then(result => {
                    json.items = result;
                    return json;
                });            
            });
        } else {
            return result;
        }        
    })
    .then(result => {
        //this call should run after all other promises and only a single time
        let event = result.authenticated ? 'valid_session' : 'invalid_session';
        console.log('222');
        proxy.send(event, result)}
    )
    .catch(err => {
        console.log('333');
        proxy.send('invalid_session', {socket_id: data.socket_id})
    })
    res.status(201).send({});
});

1 个答案:

答案 0 :(得分:1)

您可以使用async / await进行清理。在异步函数内部,您可以等待承诺的结果。

app.post('/router/join', async function (req, res, next) {
    try {
        let data = req.body;
        let {code} = await sessions.validate(data);
        let result = { authenticated: (code === 201) };     
        if (result.authenticated) {
            let cs = await contacts.getContacts(data.tenant_id);
            let json = merge(result, cs.data);            
            let items = Promise.all(cs.data.items.map(async contact => {
                let result = await messages.getLastMessage(data.tenant_id, contact.item.contact_id, data.hash_id)
                contact.item.last_message = result.code === 200 && result.data.length > 0 ? result.data[0] : null;
                return contact;
            }));   
            json.items = items;
            result = json;
        }
        let event = result.authenticated ? 'valid_session' : 'invalid_session';
        console.log('222');
        proxy.send(event, result);
        res.status(201).send({});
    } catch (err) {
        proxy.send('invalid_session', {socket_id: data.socket_id})
        next (err);
    }
});