未捕获到 promise 嵌套异步函数 promise 错误处理

uncaught in promise nested async function promise error handling

我正在尝试在我的项目中实现承诺和 async/await。我需要使用 post 获取一些数据到服务器,然后使用 javascript 执行其他进程。但我对如何处理嵌套 async/await 承诺的错误感到困惑。

问题是出现错误“Uncaught (in promise) stop!!”和字符串“停止!!”未添加到 div

这是我尝试过的:

function tunggu(waktu) {
    return new Promise((resolve) => {
    const action = setTimeout(() => {
      const str = `${waktu.toString()} milisecond has passed<br/>`;
      resolve(str);
    }, waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => {
    console.log(json);
    
    (async () => {
      div.innerHTML = 'start<br/>';
      const a = await tunggu(2000);
      div.innerHTML += a;
      throw('stop!!'); // it looks like this line is causing the error
      const b = await tunggu(3000);
      div.innerHTML += b;
    })();
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML += error
  })
<div id="asd"></div>

这(也在jsfiddle上)只是我代码的简化版本,在我的项目中,fetch使用方法POST,而js进程实际上有更多进程在里面所以我在里面用了throw因为任何地方都可能出错

there was an error "Uncaught (in promise) stop!!" and the string "stop!!" doesn't get added to the div

您通过在 .then() 处理程序中引入一个 stand-alone 异步函数打破了承诺链(它抛出,但没有自己的 .catch(),最终导致错误见)。

相反,使整个 .then() 处理程序异步:

function tunggu(waktu) {
  return new Promise((resolve) => {
    setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(async (json) => {
    console.log(json);
    
    div.innerHTML = 'start<br/>';
    const a = await tunggu(2000);
    div.innerHTML += a + '<br/>';
    throw('stop!!');
    const b = await tunggu(3000);
    div.innerHTML += b;
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML += error
  })
<div id="asd"></div>

或者,return 来自异步 IIFE 的承诺,以保持承诺链完整无缺:

function tunggu(waktu) {
  return new Promise((resolve) => {
    setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => {
    console.log(json);
    
    return (async () => {
      div.innerHTML = 'start<br/>';
      const a = await tunggu(2000);
      div.innerHTML += a + '<br/>'; 
      throw('stop!!');
      const b = await tunggu(3000);
      div.innerHTML += b;
    })();
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML += error
  })
<div id="asd"></div>