在then函数中出现了Promise错误

3

我们如何处理在promise的then函数中出现的错误?

getLocationId(lat, lon, callback)
{
    let self = this;

    return this._geocoder.reverse({lat: lat, lon: lon})
        .then(this._parse)
        .catch(function(err) {
            callback(err);
        });
}

_parse(res)
{
    if (res.length < 1)
        throw new Error('No results from Maps API');

    let value = res[0].administrativeLevels;

    if (!value || value.length < 1) {
        throw new Error('No administrative levels available');
    }

    if ('level2long' in value)
        return value.level2long;
    if ('level1long' in value)
        return value.level1long;

    throw new Error('No suitable location found');
}

例如,我该如何处理this._parse抛出的错误?我以为 promise 的 catch 函数只处理 reject 处理程序。它是否也处理在 then 中抛出的错误?

1
O.T.但相关:不需要传递callback。可以使用getLocationId(lat, lon).catch(errorHandler)来达到完全相同的效果,而不是使用getLocationId(lat, lon, errorHandler) - Roamer-1888
这也让我感到惊讶。我希望.catch()(随便叫什么都可以)只对 Promise 失败做出响应。 - Andrew
1个回答

5

在任何.then()处理程序中抛出的异常都会被Promise基础设施自动捕获,并将当前Promise链转换为拒绝状态的Promise。然后,该链将跳转到下一个.catch()处理程序,在那里,该异常将成为错误拒绝原因。

以下是一个例子:

Promise.resolve().then(function() {
    throw "foo";
}).then(function() {
     console.log("in 2nd .then() handler");     // will not get here
}).catch(function(err) {
    console.log(err);                           // will show "foo"
});

2
@Andrew - 嗯,你不能将一个异步异常转换为同步异常,这样就可以使用普通的同步try/catch捕获。所以,一旦它在promise处理程序中,它必须通过promise基础设施来处理。你不必在本地处理它。你可以让它沿着promise链传播,并在上层的某个调用者级别上处理它,但是.catch()或者使用async/await时的等效方法必须在某个地方捕获它。 - jfriend00
1
@Andrew - 请记住,在.then()处理程序中发生的异常是异步的。无论是什么同步代码调用了它,已经返回并且不再活动。所以,这就是为什么你不能同步地捕获它的原因。 - jfriend00
如果我无法控制或不知道可能出现的错误,那么我如何区分 Promise 错误和 .then() 代码中的错误呢? - Andrew
@Andrew - 你在同一个地方捕获它们。它们只是不同的异常而已。与在同步代码中使用try/catch一样,其中编码错误和引发异常的程序条件都会抛出异常,只是异常类型不同而已。 - jfriend00
虽然确实有所不同,但这正是我的问题所在:如果 Promise 失败,我想显示一种错误;如果 .then() 代码失败,我希望以不同的方式处理它。如果我不知道会出现什么样的错误,那么我需要一种区分它们的方法。我想我可以在 .then() 内部使用 try/catch,然后抛出自己的错误,或者类似的操作... - Andrew
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接