如何正确控制Javascript异常处理的执行流

如何正确控制Javascript异常处理的执行流,javascript,node.js,exception,Javascript,Node.js,Exception,在真实代码中,我从SQL数据库获取帐户。然后,对于账户的每个账户,我调用了一些方法a(),b(),c() 我想要的是,如果在调用a(),b(),c()时,由于任何原因出现错误(异常),执行将停止并继续循环中的下一个迭代,即下一个帐户 因此,给定该示例代码: const accounts = ['a1', 'a2', 'a3'] async function a() { await console.log('A'); } async function b() { await co

在真实代码中,我从SQL数据库获取
帐户
。然后,对于
账户的每个
账户
,我调用了一些方法
a()
b()
c()

我想要的是,如果在调用
a()
b()
c()
时,由于任何原因出现错误(异常),执行将停止并继续循环中的下一个迭代,即下一个帐户

因此,给定该示例代码:

const accounts = ['a1', 'a2', 'a3']

async function a() {
    await console.log('A');
}
async function b() {
    await console.log('B');
    throw new Error('B throws Error');
}
async function c() {
    await console.log('C');
}

async function main() {
    for (const account of accounts) {
        try {
            await a();
            await b();
            await c();
        } catch(e) {}
    }
}

main();
将调用
a()
b()
,并给出以下输出:

A
B
A
B
A
B
然后,如果我在
b()中添加try/catch

运行该代码时,我会得到:

A
B
C
A
B
C
A
B
C
尽管在
b()
中引发了异常,但由于try/catch

我的问题是:

如果我不能使应用程序在catch中处于可靠状态。。。是 有一种方法可以在内部方法中继续使用try/catch-s,但是 停止执行以便
c()
不会执行

如果我使用异常的方式是错误的。你能帮我解释一下正确的用法吗

如果我不能使应用程序在catch中处于可靠状态。。。有没有一种方法可以让我在内部方法中继续使用try/catch-s,但停止执行,这样c()就不会被执行

是的,只需在
b()
中重新显示异常,允许
b()
的调用者看到它。它对
async
函数和promise
.then()
处理程序的作用与在同步异常世界中的作用完全相同。这是特意设计的,旨在为基于承诺的异步/等待异常/拒绝提供类似的感觉

async function b() {
    try {
        await console.log('B');
        throw new Error('B throws Error');
    } catch(e) {
        // pseudo code for some condition that you test to determine
        // if you want to "eat" the error or let the caller see it
        if (can't continue safely) {
            // allow the exception to propagate to the caller
            throw e;    
        }
    }
}

我假定您知道
async
await
是用于异步操作的,而这些操作实际上并没有显示在代码中。没有人会在实际代码中执行
wait console.log(…)
,因为这是一个不返回承诺的同步操作,所以使用
wait
是毫无意义的。我希望您这样做只是为了一个简短的演示。

我认为重新播放是一种不好的做法。不是吗?也许这是普遍的和可以接受的。。。是的,我在控制台中使用waits,因为在实际代码中,我可以使用返回承诺的函数,并在它们解析时从中获取值。@Jeflopo-Rethrow就是这样做的。这是捕获错误、检查错误或记录错误,然后决定让错误传播回调用方的适当方法。这不是一个坏习惯。如果您需要在本地捕获它,然后让它传播回调用方,那么这是正确的做法。有时,你不会在本地捕捉到它,而是让它一直传播。但是,如果出于某种原因需要在本地捕获它,那么rethrow是决定让调用方看到它的唯一方法。这很普通。我不确定。。。在这种情况下,当您说“传播回调用者”时,将是对
上下文的
for,其中调用了
b()
,换句话说,是执行流中
b()
的父级,对吗?@Jeflopo-是的,返回到调用
b()
的代码。在您的情况下,它将被
main()
中的
for
循环中的try/catch块捕获,因为您使用了
wait b()
。因此,
wait
将看到被拒绝的承诺从
b()
返回并在本地抛出。
async function b() {
    try {
        await console.log('B');
        throw new Error('B throws Error');
    } catch(e) {
        // pseudo code for some condition that you test to determine
        // if you want to "eat" the error or let the caller see it
        if (can't continue safely) {
            // allow the exception to propagate to the caller
            throw e;    
        }
    }
}