【问题标题】:Code throwing unhandled rejection error when running promise运行 promise 时代码抛出未处理的拒绝错误
【发布时间】:2022-02-16 06:49:44
【问题描述】:

我正在尝试编写一个 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);
});

【问题讨论】:

  • 不清楚您所说的“解决并拒绝所需变量的承诺”是什么意思。这不是承诺的作用。由于您的代码没有执行任何异步操作,因此您不应在此处使用 Promise。

标签: javascript async-await try-catch es6-promise


【解决方案1】:

通过在两个不同的地方调用.then().catch() 处理程序,您实际上会得到两个不同的promise - 每个.then().catch() 返回一个新的promise。 .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);
});

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

相反,您可以直接在与.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>

【讨论】:

  • 精湛的解释。你的解决方案奏效了!谢谢!
【解决方案2】:

这不起作用的原因是因为您在第一个上没有 .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);
    });

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

此外,我建议使用异步等待,因为它更易于阅读且更易于管理。您可以通过创建一个返回新 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();

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 2018-03-19
    • 1970-01-01
    • 2018-04-27
    • 2016-09-18
    • 2016-11-10
    • 2016-02-19
    • 2018-12-24
    • 1970-01-01
    相关资源
    最近更新 更多