嵌套异步函数调用中的错误管理

问题描述 投票:0回答:1

我正在使用 Office JS API 开发 Excel 加载项。我有一个任务窗格正在运行类似于以下内容的代码:

var failA = true
var failB = true

// In reality this is Excel.run, and it injects a context 
async function run(f) { 
  f()
}

// Simulate a failing async call
async function fail(message, delay) {
    setTimeout(()=>{
    throw new Error(message)
   }, delay)
}

// Simulate a successful async call
async function success(message, delay) {
    setTimeout(delay)
}

async function doA() {
    console.log("Inside A");
  if (failA) {
    console.log("Failing A");
    await fail("Error A", 1000)
  } else {
    success("Success A")
  }
  console.log("Done A")
}

async function doB() {
    console.log("Inside B");
  if (failB) {
    console.log("Failing B");
    await fail("Error B", 1000)
  } else {
    success("Success B")
  }
  console.log("Done B")
}

async function main () {
try {
    // This is how Excel.run is called in all the Office samples
    await run(async ()=>{
    console.log("Start main");
    await doA();
    console.log("Between A and B");
    await doB();
    console.log("Finished");
  })}
catch (error) {
    console.log("ERROR: " + error.message)
  }
}

// Need to await main in an async context. In reality main is run from a button
(async () => await main())()
.as-console-wrapper { min-height: 100%!important; top: 0; }

我预计

doA
中的错误会冒泡并中断
doB
的进一步执行。输出应该是:

Start main
Inside A
Failing A
ERROR: Error A

相反,我得到的是:

Start main
Inside A
Failing A
Done A
Between A and B
Inside B
Failing B
Done B
Finished

随后是两个未捕获的异常

Error A
Error B

我做错了什么?我可以在不将

doA
doB
分别包装在
try...catch
块中的情况下实现我期望的行为吗?

javascript exception async-await office-js
1个回答
0
投票

setTimeout
对promise一无所知。相反,使用基于承诺的睡眠来等待。

您还忘记了

await f()
函数中的
run

var failA = true
var failB = true

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

// In reality this is Excel.run, and it injects a context 
async function run(f) {
    await f()
}

// Simulate a failing async call
async function fail(message, delay) {
    await sleep(delay);
    throw new Error(message)
}

// Simulate a successful async call
async function success(message, delay) {
    await sleep(delay);
}

async function doA() {
    console.log("Inside A");
    if (failA) {
        console.log("Failing A");
        await fail("Error A", 1000)
    } else {
        success("Success A")
    }
    console.log("Done A")
}

async function doB() {
    console.log("Inside B");
    if (failB) {
        console.log("Failing B");
        await fail("Error B", 1000)
    } else {
        success("Success B")
    }
    console.log("Done B")
}

async function main() {
    try {
        // This is how Excel.run is called in all the Office samples
        await run(async () => {
            console.log("Start main");
            await doA();
            console.log("Between A and B");
            await doB();
            console.log("Finished");
        })
    }
    catch (error) {
        console.log("ERROR: " + error.message)
    }
}

// Need to await main in an async context. In reality main is run from a button
(async () => await main())()
.as-console-wrapper { min-height: 100%!important; top: 0; }

© www.soinside.com 2019 - 2024. All rights reserved.