运行 promise 时代码抛出未处理的拒绝错误

Code throwing unhandled rejection error when running promise

我正在尝试编写一个 Javascript 承诺来解决和拒绝所需的变量。我在控制台 运行 后收到以下错误消息

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
 code: 'ERR_UNHANDLED_REJECTION'

这是我的代码

Js文件:


const grimeUserLeft = false;
const userWatchingGrimeVids = true;

let grimePromise = new Promise((resolve, reject) => {
  if (grimeUserLeft) {
    reject("User Left");
  } else if (userWatchingGrimeVids) {
    reject("This user is a G");
  } else {
    resolve("Congrats. Your channel doesn't suck");
  }
});

grimePromise.then((message) => {
  console.log("Success: " + message);
});
grimePromise.catch((message) => {
  console.log("You Failed: " + message);
});

通过在两个不同的地方调用 .then().catch() 处理程序,您实际上得到了两个不同的承诺 - 每个 .then().catch() returns一个新的。 .then() 返回的承诺将 不会 被单独的 .catch() 处理程序捕获:

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

let grimePromise = new Promise((resolve, reject) => {
  if (grimeUserLeft) {
    reject("User Left");
  } else if (userWatchingGrimeVids) {
    reject("This user is a G");
  } else {
    resolve("Congrats. Your channel doesn't suck");
  }
});

grimePromise
  .then((message) => {
    console.log("Success: " + message);
  })
  .catch(() => console.log(1));

grimePromise.catch((message) => {
  console.log(2);
  console.log("You Failed: " + message);
});

因此,一个承诺变成了两个。他们每个人都会采用原始​​承诺的状态。当原始承诺被拒绝时,派生的承诺都会拒绝。然而只处理了一个。

相反,您可以直接在与 .then() 相同的承诺链中指定 .catch():

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

let grimePromise = new Promise((resolve, reject) => {
  if (grimeUserLeft) {
    reject("User Left");
  } else if (userWatchingGrimeVids) {
    reject("This user is a G");
  } else {
    resolve("Congrats. Your channel doesn't suck");
  }
});

grimePromise
  .then((message) => {
    console.log("Success: " + message);
  })
  .catch((message) => {
    console.log("You Failed: " + message);
  });
<h1>Check the browser console - no unhandled promise rejections</h1>

或者,在 then():

中指定两个处理程序

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

let grimePromise = new Promise((resolve, reject) => {
  if (grimeUserLeft) {
    reject("User Left");
  } else if (userWatchingGrimeVids) {
    reject("This user is a G");
  } else {
    resolve("Congrats. Your channel doesn't suck");
  }
});

grimePromise
  .then(
    (message) => {
      console.log("Success: " + message);
    },
    (message) => {
      console.log("You Failed: " + message);
    }
  );
<h1>Check the browser console - no unhandled promise rejections</h1>

这不起作用的原因是您在第一个上没有 .catch()。它正在抛出一个拒绝,但你没有用 catch 优雅地处理它,所以它抛出了。

这是您的代码工作 - 我只是将您的 catch 块移动到 .then 之后:

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

const grimePromise = new Promise((resolve, reject) => {
    if (grimeUserLeft) {
        reject('User Left');
    } else if (userWatchingGrimeVids) {
        reject('This user is a G');
    } else {
        resolve("Congrats. Your channel doesn't suck");
    }
});

grimePromise
    .then((message) => {
        console.log('Success: ' + message);
    })
    .catch((message) => {
        console.log('You Failed: ' + message);
    });

作为提示,您应该只在函数以某种方式不成功时才拒绝。这可能是超时、网络错误、输入不正确等。reject 中的任何内容在理想情况下都应该是错误。

此外,我建议使用 async await,因为它更易于阅读和管理。你可以通过创建一个 returns 你的新 Promise 的函数来轻松地做到这一点,然后像这样等待它:

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

const grime = () => {
    return new Promise((resolve, reject) => {
        if (grimeUserLeft) {
            reject(new Error('User Left'));
        } else if (userWatchingGrimeVids) {
            resolve('This user is a G');
        } else {
            resolve("Congrats. Your channel doesn't suck");
        }
    });
};

const doStuff = async () => {
    try {
        const result = await grime();
        console.log(result);
    } catch (error) {
        console.error(error);
    }
};

doStuff();

要使其真正异步,理想情况下您应该在 promise 中做一些异步的事情。这可以用 setTimeout 来证明:

const grimeUserLeft = false;
const userWatchingGrimeVids = true;

const grime = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (grimeUserLeft) {
                reject(new Error('User Left'));
            } else if (userWatchingGrimeVids) {
                resolve('This user is a G');
            } else {
                resolve("Congrats. Your channel doesn't suck");
            }
        }, 2000);
    });
};

const doStuff = async () => {
    try {
        const result = await grime();
        console.log('result finished after 2 seconds');

        console.log(result);
    } catch (error) {
        console.error(error);
    }
};

doStuff();