首页 > 解决方案 > 我无法处理承诺拒绝

问题描述

我有一项服务,可以分析网站,压缩它们的来源,如 CSS 文档、图像等。我有 2 个函数,一个是socket.on()带有异步回调函数的 Socket.IO 方法。另一个是服务的主要功能。

socket.on('run', async options => {
    debug(`${options.target} Adresine Bir Kullanıcı İstek Yaptı!`);
    let user = null;
    console.log(options);
    if(options.token) {
        user = await User.findById(jwt.verify(options.token, config.get('jwtPrivateKey'))._id);
        options.userId = user._id.toString();
    } else if(options.visitor) {
        user = await Visitor.findById(options.visitor._id);
        if(user.report) {
            return socket.emit('error', new Error('You have exceeded your report limit'));
        } else {
            options.userId = user._id.toString();
        }
    }
    if(options.userId) {
        let userType = await UserType.find({ name: user.type });
        if(userType.length > 0 && ((user.type == 'Visitor' && user.report == undefined) || (user.reports.length < userType[0].rights.reportsLimit.limit || userType[0].rights.reportsLimit.unlimited))) {
            options.rights = userType[0].rights;
            let { error, data } = await wrapper(runService(options.target, options, socket));
            if(error) {
                console.log('Here', error);
                return socket.emit('error', error);
            }
        .
        .
        .
        }
    .
    .
    .
    }
});

在上述函数中,

let { error, data } = await wrapper(runService(options.target, options, socket));
if(error) {
    console.log('Here', error);
    return socket.emit('error', error);
}

这部分很重要,因为我runService使用名为wrapper. 包装函数是这样的;

const wrapper = promise => (
    promise
        .then(data => ({ data, error: null }))
        .catch(error => ({ error, data: null }))
);

在我的主要异步服务功能中,我只抛出一个错误;

async function runService(target, options, socket) {
     throw new Error('any error');
}

但是预期的输出与实际输出有很大的不同。这是此代码的输出;

Here Error: any error
    at startService (C:\Projeler\OpDetect\Background-Service\lib\app.js:404:11)
    at Socket.socket.on (C:\Projeler\OpDetect\Background-Service\app.js:73:57)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16600) UnhandledPromiseRejectionWarning: Error: any error
    at startService (C:\Projeler\OpDetect\Background-Service\lib\app.js:404:11)
    at Socket.socket.on (C:\Projeler\OpDetect\Background-Service\app.js:73:57)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16600) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
 This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:16600) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate

具有非零退出代码的 Node.js 进程。

我对输出的期望是这样的;

Here Error: any error
    at startService (C:\Projeler\OpDetect\Background-Service\lib\app.js:404:11)
    at Socket.socket.on (C:\Projeler\OpDetect\Background-Service\app.js:73:57)
    at process._tickCallback (internal/process/next_tick.js:68:7)

因为我已经用我的包装函数处理了承诺拒绝并捕获了拒绝,为什么拒绝时还有 2 个UnhandledPromiseRejectionWarning错误?

还有,线,

return socket.emit('error', error);

不是无缘无故打电话。if当陈述为真时应该调用它。为什么不socket.emit调用这个函数?

标签: javascriptasynchronoussocket.iopromiseunhandled-exception

解决方案


作为try {} catch(){}async/await 的最佳实践。

例如。

userUtils.signUp = async (userName) => {
try {
    const callFunction = await userUtils.checkExistancy(userName);

    if (!callFunction.isExist) {
        ...
    } else {
        ...
    }
} catch (err) {
    console.log(err);
    throw err;
 }

};

在你的情况下,它会像

socket.on('run', async options => {
try {
    user = await User.findById(jwt.verify(options.token, config.get('jwtPrivateKey'))._id);
    options.userId = user._id.toString();
    return true;
} catch (err) {
    throw err;
}});

推荐阅读