考虑以下(人为)示例:

import Promise from 'bluebird';

const resolvedPromise = () => {
    return Promise.resolve('Test');
};

const asyncFunc = async (asyncResource) => {
    await resolvedPromise();
    await asyncResource.fetchItem();
};


describe('async/await', () => {
    it('should throw an error', (done) => {
        const mockAsyncResource = jasmine.createSpyObj('mockAsyncResource', ['fetchItem']);

        const mockError = Promise.reject(new Error('HTTP 401 - Access Denied'));

        mockAsyncResource.fetchItem.and.returnValue(mockError);

        return asyncFunc(mockAsyncResource).catch(err => {
            expect(err.message).toEqual('HTTP 401 - Access Denied');
            done();
        });
    });
});


我收到以下输出:

1) async/await
Unhandled rejection Error: HTTP 401 - Access Denied
... (error stack trace)

✔ should throw an error


规范通过了,但是Bluebird抱怨未处理的拒绝错误。

由于等待的阻塞性质,mockError是否在第二个await有机会调用(处理)mockError承诺之前报告未处理的拒绝?

处理这种情况的最佳方法是什么?我发现了promise.suppressUnhandledRejections(),就像使用它一样简单吗?

最佳答案

我认为这是由于混合了两种不同类型的诺言而引起的问题。您正在使用bluebird的Promise创建已解决/已拒绝的模拟承诺,但是await返回本地Promise

如果您在chrome控制台上尝试以下操作,则仅使用本机Promise时,就会看到它按预期工作:

let resolvedPromise = () => {
    return Promise.resolve('Test');
};

let asyncFunc = async (asyncResource) => {
    await resolvedPromise();
    await asyncResource.fetchItem();
};

let mockAsyncResource = {fetchItem: () => Promise.reject(new Error("foo"))};

asyncFunc(mockAsyncResource).catch((e) => console.log('handled'))


如果您想坚持创建bluebird promise,则可能需要用bluebird的Promise.try包装异步功能,尽管我无法对此进行测试:

let asyncFunc = async (asyncResource) => {
    return Promise.try(async () => {
        await resolvedPromise();
        await asyncResource.fetchItem();
    });
};

关于node.js - Bluebird,Jasmine和异步函数的未处理拒绝错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42497508/

10-12 04:47