javascript - 在promise内部出错后继续子循环-try/catch

标签 javascript loops error-handling promise continue

我非常怀疑我编写的代码是实现目标的有效/最佳方式。

我有一个 promise ,可以进行SQL查询,完成后,我遍历一个数组及其子数组+对象。即使任何子循环由于任何特定原因而失败,我也希望内部循环继续执行,直到遍历整个数组为止。现在我有一个“try/catch” hell ,我怀疑这是正确的方法。但是,我应该说它按预期运行,但是代码有多糟糕?

new Promise((resolve, reject) => {
    sqlConnection.execute(
    'INSERT INTO pms (userId, message, conversationId) VALUES (?, ?, ?)',
        [userid, receivedMsg, receivedConvId],
        function(err, results) {
            if (err) throw err;
            resolve("DEBUG: PM from "+username+" into conv "+receivedConvId+" was sucessfully inserted to DB");
        }   
    );  
}).then(() => {
    users.forEach(function(userobj, i, arr) {
        try {
            if (userobj.memberof.includes(receivedConvId)) {
                let rcptUsername = userobj.username;    
                let rcptUserid = userobj.userid;
                debug(rcptUsername+" is member of the group "+receivedConvId);
                Object.keys(userobj.sessions).forEach(function(session) {
                    try {
                    userobj.sessions[session].forEach(function(wsConn) {
                        try {   
                            debug("DEBUG: Broadcasting message to "+rcptUsername+" for connections inside session "+session);
                            wsConn.send(JSON.stringify(msgToSend));
                        } catch(err) {
                            errorHandler(err);
                        }   
                    }); 
                    } catch(err) {
                    errorHandler(err);
                }   
            }); 
        }   
    } catch(err) {
        errorHandler(err); 
     }
});
}).catch((err) => {
    debug(err);
}).then(() => {
    debug("INFO: Message broadcast finished");
});

我正在遍历的数组如下所示:
[ 
{ username: 'Root',
    userid: '1',
    memberof: [ 1, 2, 3 ],
    sessions: 
        { 
            pvkjhkjhkj21kj1hes5: [Array],
            '4duihy21hkk1jhhbbu52': [Array] 
        } 
},
{ 
    username: 'Admin',
    userid: '2',
    memberof: [ 1, 2, 4 ],
    sessions: 
        { 
            cg2iouoiuiou111uuok7: [Array],
            sl1l3k4ljkjlkmmmmkllkl: [Array] 
        } 
} 
]

感谢您的任何建议。

最佳答案

假设wsConnhttps://github.com/websockets/ws websocket-那么您使用的代码无论如何都只会“检测”即时错误-不会捕获任何套接字写入失败

在任何wsConn.send完成之前,您还将输出“INFO:消息广播已完成”-因为它是异步的

幸运的是,.send有一个回调,一旦发送完成,就会在错误或成功时回调该回调-这解决了两个问题

使用promise是一个好主意,除了除了初始SQL执行外,您没有对其他任何东西使用promise,这就是为什么您最终陷入嵌套 hell 的原因

我非常有信心(没有完整的代码,我不确定),下面的代码不仅可以运行,而且嵌套更少

new Promise((resolve, reject) => {
    sqlConnection.execute(
        'INSERT INTO pms (userId, message, conversationId) VALUES (?, ?, ?)',
        [userid, receivedMsg, receivedConvId],
        (err, results) => {
            if (err) {
                return reject(err);
            }
            resolve("DEBUG: PM from " + username + " into conv " + receivedConvId + " was sucessfully inserted to DB");
        }
    );
}).then(() => {
    const allConnectionsArray = users
    .filter(({memberof}) => memberof.includes(receivedConvId)) // filter out any userobj we aren't going to send to
    .map(({rcptUsername, rcptUserid, sessions}) => {
        debug(rcptUsername + " is member of the group " + receivedConvId);
        const userSessionsArray = Object.entries(sessions).map(([session, value]) => {
            return value.map((wsConn, index) => {
                return { wsConn, rcptUserid, rcptUsername, session, index };
            })
        });
        return [].concat(...userSessionsArray); // flatten the array
    });
    const promises = [].concat(...allConnectionsArray) // flatten the array
    .map(({ wsConn, rcptUserid, rcptUsername, session, index }) => {
        debug("DEBUG: Broadcasting message to " + rcptUsername + " for connections inside session " + session);
        return new Promise((resolve) => {
            wsConn.send(JSON.stringify(msgToSend), err => {
                if (err) {
                    return resolve({ rcptUserid, rcptUsername, session, index, err });
                }
                resolve({ rcptUserid, rcptUsername, session, index, err: false });
            });
        });
    });
    return Promise.all(promises);
}).then(results => {
    /* results is an array of {
        rcptUserid
        rcptUsername
        session
        index //(index is the ordinal position in user.sessions array
        err //(===false if success)
    }
    */
    debug("INFO: Message broadcast finished");
}).catch(error => {
    // the only error caught here would be in the `return reject(err);` in the sql execute,
    // because any failure in wsConn.send is a resolved promise (with an error property)
    // unless I'm not seeing something obvious, they are the only possible places an error could be thrown anyway
});

关于javascript - 在promise内部出错后继续子循环-try/catch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52567983/

相关文章:

javascript - jQuery 选择器除父级为 div 之外的所有元素

javascript - 将带有类(及其底层元素)的现有 div 元素添加到 div

ruby - 遍历 Ruby 数组最惯用的方法,满足任意条件时退出?

sql-server - SQL 抛出算术溢出错误

javascript - 如何使用音频文件中的振幅为图像大小制作动画?

javascript - AngularJs 销毁广播并发出监听器

java - 如何用函数处理catch block ?

flutter - 如何解决此 StackOverflow 错误

javascript - 在 Extjs 中加载 HtmlEditor 内的内容

c - Else 语句在 strcmp 中返回错误结果(比较哈希值)(已更新)