Bluebird 中未处理的拒绝

Unhandled rejection in Bluebird

我有以下代码。当 f2 没有抛出错误时它工作正常。

如果有错误,它会生成一个Unhandled rejection Error

重写代码以避免 Unhandled rejection Error 并将其正确传播到 f1 中的 catch 的正确方法是什么?

let Bluebird = require('bluebird'),
    mkdirp = Bluebird.promisify(require('mkdirp')),
    request = Bluebird.promisify(require('request')),
    writeFile = Bluebird.promisify(require('fs').writeFile);

function f1() {
    .........
    f2(path, fileName, options).then(.....).catch(....); 
}

function f2(path, fileName, options) {
    p = mkdirp(path).then(request(options).then(res => {
        if (res[0].statusCode === 200) {
            writeFile(fileName, res[0].body);
            return res[0].body;
        } else {
            throw new Error(res[0].statusCode + ': ' + res[0].body);
        }
    }));
    return p;
}

问题是您在 f2 中将承诺传递给 .then().then() 会忽略任何不是函数的东西,所以 f2 实际上 returning 是对 mkdirp(this.path) 的承诺,出于某些原因这是一个大错误。如果在 request(options)then 处理程序中抛出错误,那么将没有任何东西可以处理它。

此外,您没有采取任何措施来处理来自 writeFile 的可能错误。如果您调用 writeFile,您要么需要 return 包含它的承诺链,要么添加逻辑以在 f2.

中处理它

因为看起来你可以在这里并行 运行 mkdirp()request(),但你没有使用 mkdirp() 的结果我会说这是要走的路:

function f2(path, fileName, options) {
    var p = mkdirp(path).return(request(options)).then(res => {
        if (res[0].statusCode === 200) {
            return writeFile(fileName, res[0].body)
            .return(res[0].body);
        } else {
            throw new Error(res[0].statusCode + ': ' + res[0].body);
        }
    });
    return p;
}