我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript中怎么实现错误处理

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript中怎么实现错误处理

JavaScript中怎么实现错误处理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

使用 Promise 处理错误

为了演示 Promise 处理方式,我们先回到一开始的那个事例:

function toUppercase(string) {   if (typeof string !== "string") {     throw TypeError("Wrong type given, expected a string");   }    return string.toUpperCase(); }  toUppercase(4);

相对简单抛出异常,我们可以使用 Promise.reject 和Promise.resolve:

function toUppercase(string) {   if (typeof string !== "string") {     return Promise.reject(TypeError("Wrong type given, expected a string"));   }    const result = string.toUpperCase();    return Promise.resolve(result); }

因为使用了 Promise ,所以可以使用 then 来接收返回的内容,或者用 catch 来捕获出现的错误。

toUppercase(99)   .then(result => result)   .catch(error => console.error(error.message));

上面的执行结果:

Wrong type given, expected a string

除了 then 和 catch , Promise 中还有 finally 方法,这类似于try/catch 中的 finally。

toUppercase(99)   .then(result => result)   .catch(error => console.error(error.message))   .finally(() => console.log("Run baby, run"));

Promise, error, 和 throw

使用 Promise.reject 可以很方便的抛出错误:

Promise.reject(TypeError("Wrong type given, expected a string"));

除了Promise.reject,我们也可以通过抛出异常来退出 Promise。

考虑以下示例:

Promise.resolve("A string").then(value => {   if (typeof value === "string") {     throw TypeError("Expected a number!");   } });

要停止异常传播,我们照常使用catch:

Promise.resolve("A string")   .then(value => {     if (typeof value === "string") {       throw TypeError("Expected a number!");     }   })   .catch(reason => console.log(reason.message));

这种模式在fetch中很常见:

fetch("https://example-dev/api/")   .then(response => {     if (!response.ok) {       throw Error(response.statusText);     }      return response.json();   })   .then(json => console.log(json));

这里可以使用catch拦截异常。如果我们失败了,或者决定不捕获它,异常可以在堆栈中自由冒泡。

使用 Promise 来处理定时器中的异常

使用定时器或事件无法捕获从回调引发的异常。

function failAfterOneSecond() {   setTimeout(() => {     throw Error("Something went wrong!");   }, 1000); }  // DOES NOT WORK try {   failAfterOneSecond(); } catch (error) {   console.error(error.message); }

解决方案就是使用 Promise:

function failAfterOneSecond() {   return new Promise((_, reject) => {     setTimeout(() => {       reject(Error("Something went wrong!"));     }, 1000);   }); }

使用reject,我们启动了一个 Promise 拒绝,它携带一个错误对象。

此时,我们可以使用catch处理异常:

failAfterOneSecond().catch(reason => console.error(reason.message));

使用 Promise.all 来处理错误

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise  都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);

const promise1 = Promise.resolve("All good!"); const promise2 = Promise.resolve("All good here too!");  Promise.all([promise1, promise2]).then((results) => console.log(results));  // [ 'All good!', 'All good here too!' ]

如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

const promise1 = Promise.resolve("All good!"); const promise2 = Promise.reject(Error("No good, sorry!")); const promise3 = Promise.reject(Error("Bad day ..."));  Promise.all([promise1, promise2, promise3])   .then(results => console.log(results))   .catch(error => console.error(error.message));  // No good, sorry!

同样,无论Promise.all的结果如何运行函数,finally 都会被执行:

Promise.all([promise1, promise2, promise3])   .then(results => console.log(results))   .catch(error => console.error(error.message))   .finally(() => console.log("Always runs!"));

使用 Promise.any 来处理错误

Promise.any() (Firefox > 79, Chrome > 85) 接收一个 Promise 可迭代对象,只要其中的一个  promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises  都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error  的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。

const promise1 = Promise.reject(Error("No good, sorry!")); const promise2 = Promise.reject(Error("Bad day ..."));  Promise.any([promise1, promise2])   .then(result => console.log(result))   .catch(error => console.error(error))   .finally(() => console.log("Always runs!"));

在这里,我们使用catch处理错误,输出如下:

AggregateError: No Promise in Promise.any was resolved Always runs!

AggregateError对象具有与基本Error相同的属性,外加errors属性:

//   .catch(error => console.error(error.errors)) //

此属性是由reject产生的每个单独错误的数组

[Error: "No good, sorry!, Error: "Bad day ..."]

使用 Promise.race 来处理错误

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的  promise就会解决或拒绝。

const promise1 = Promise.resolve("The first!"); const promise2 = Promise.resolve("The second!");  Promise.race([promise1, promise2]).then(result => console.log(result));  // The first!

这里说明,第一个 Promise 比第二个行执行完。那包含拒绝的情况又是怎么样的?

const promise1 = Promise.resolve("The first!"); const rejection = Promise.reject(Error("Ouch!")); const promise2 = Promise.resolve("The second!");  Promise.race([promise1, rejection, promise2]).then(result =>   console.log(result) );  // The first!

如果把reject放在第一个又会怎么样?

const promise1 = Promise.resolve("The first!"); const rejection = Promise.reject(Error("Ouch!")); const promise2 = Promise.resolve("The second!");  Promise.race([rejection, promise1, promise2])   .then(result => console.log(result))   .catch(error => console.error(error.message));  // Ouch!

使用 Promise.allSettled 来处理错误

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

考虑下面示例:

const promise1 = Promise.resolve("Good!"); const promise2 = Promise.reject(Error("No good, sorry!"));  Promise.allSettled([promise1, promise2])   .then(results => console.log(results))   .catch(error => console.error(error))   .finally(() => console.log("Always runs!"));

我们传递给Promise.allSettled一个由两个Promise组成的数组:一个已解决,另一个被拒绝。

这种情况 catch 不会被执行, finally 永远会执行。

[   { status: 'fulfilled', value: 'Good!' },   {     status: 'rejected',     reason: Error: No good, sorry!   } ]

使用 async/await 来处理错误

为了简单起见,我们使用前面的同步函数toUppercase,并通过在function关键字前放置async来将其转换为异步函数

async function toUppercase(string) {   if (typeof string !== "string") {     throw TypeError("Wrong type given, expected a string");   }    return string.toUpperCase(); }

只要在函数前面加上async,该函数就会返回一个Promise。这意味着我们可以在函数调用之后进行then、catch和finally 操作

async function toUppercase(string) {   if (typeof string !== "string") {     throw TypeError("Wrong type given, expected a string");   }    return string.toUpperCase(); }  toUppercase("abc")   .then(result => console.log(result))   .catch(error => console.error(error.message))   .finally(() => console.log("Always runs!"));

当从 async 函数抛出异常时,我们就可以使用 catch 来捕获。

最重要的是,除了这种方式外,我们可以还使用try/catch/finally,就像我们使用同步函数所做的一样。

async function toUppercase(string) {   if (typeof string !== "string") {     throw TypeError("Wrong type given, expected a string");   }    return string.toUpperCase(); }  async function consumer() {   try {     await toUppercase(98);   } catch (error) {     console.error(error.message);   } finally {     console.log("Always runs!");   } }  consumer();

输出:

Wrong type given, expected a string Always runs!

使用 async generators 来处理错误

JavaScript中的async generators是能够生成 Promises 而不是简单值的生成器函数。

async function* asyncGenerator() {   yield 33;   yield 99;   throw Error("Something went wrong!"); // Promise.reject }

基于 Promise,此处适用于错误处理的相同规则。在异步生成器中 throw 将会触发 Promise  的reject,我们可以使用catch对其进行拦截。

为了使用异步生成器的 Promise,我们可以这样做:

  • then 方法

  • 异步遍历

从上面我们知道,在两次调用 yield之后,下一次会抛出一个异常:

const go = asyncGenerator();  go.next().then(value => console.log(value)); go.next().then(value => console.log(value)); go.next().catch(reason => console.error(reason.message));

输出结果:

{ value: 33, done: false } { value: 99, done: false } Something went wrong!

别一种是使用 异步遍历与for await...of:

async function* asyncGenerator() {   yield 33;   yield 99;   throw Error("Something went wrong!"); // Promise.reject }  async function consumer() {   for await (const value of asyncGenerator()) {     console.log(value);   } }  consumer();

有了 async/await 我们可以使用 try/catch 来捕获异常:

async function* asyncGenerator() {   yield 33;   yield 99;   throw Error("Something went wrong!"); // Promise.reject }  async function consumer() {   try {     for await (const value of asyncGenerator()) {       console.log(value);     }   } catch (error) {     console.error(error.message);   } }  consumer();

输出结果:

33 99 Something went wrong!

从异步生成器函数返回的迭代器对象也具有throw()方法,非常类似于其同步副本。在此处的迭代器对象上调用throw()不会引发异常,但是会被Promise拒绝

async function* asyncGenerator() {   yield 33;   yield 99;   yield 11; }  const go = asyncGenerator();  go.next().then(value => console.log(value)); go.next().then(value => console.log(value));  go.throw(Error("Let's reject!"));  go.next().then(value => console.log(value)); // value is undefined

要从外部处理这种情况,我们可以做:

go.throw(Error("Let's reject!")).catch(reason => console.error(reason.message));

Node 中的错误处理

Node 中的同步错误处理

Node.js 中的同步错误处理与到目前为止所看到的并没有太大差异。对于同步,使用 try/catch/finally 就可以很好的工作了。

Node.js 中的异步错误处理:回调模式

对于异步代码,Node.js 主要使用这两种方式:

  • 回调模式

  • event emitters

在回调模式中,异步 Node.js API 接受一个函数,该函数通过事件循环处理,并在调用堆栈为空时立即执行。

考虑以下代码:

const { readFile } = require("fs");  function readDataset(path) {   readFile(path, { encoding: "utf8" }, function(error, data) {     if (error) console.error(error);     // do stuff with the data   }); }

我们可以看到,这里处理错误的方式是使用了回调:

// function(error, data) {     if (error) console.error(error);     // do stuff with the data   } //

如果使用fs.readFile读取给定路径而引起任何错误,我们将获得一个错误对象。

在这一点上,我们可以:

  • 简单的把对象错误打出来

  • 抛出错误

  • 把错误传到另一个回调

我们可以抛出一个异常

const { readFile } = require("fs");  function readDataset(path) {   readFile(path, { encoding: "utf8" }, function(error, data) {     if (error) throw Error(error.message);     // do stuff with the data   }); }

但是,与 DOM 中的事件和定时器一样,此异常将使程序崩溃。通过try/catch捕获它是不起作用的:

const { readFile } = require("fs");  function readDataset(path) {   readFile(path, { encoding: "utf8" }, function(error, data) {     if (error) throw Error(error.message);     // do stuff with the data   }); }  try {   readDataset("not-here.txt"); } catch (error) {   console.error(error.message); }

如果我们不想使程序崩溃,则将错误传递给另一个回调是首选方法:

const { readFile } = require("fs");  function readDataset(path) {   readFile(path, { encoding: "utf8" }, function(error, data) {     if (error) return errorHandler(error);     // do stuff with the data   }); }

这里的errorHandler顾名思义,是一个用于错误处理的简单函数:

function errorHandler(error) {   console.error(error.message);   // do something with the error:   // - write to a log.   // - send to an external logger. }

Node.js 中的异步错误处理:event emitters

在 Node.js 中所做的大部分工作都是基于事件的。大多数情况下,emitter object 和一些观察者进行交互以侦听消息。

Node.js中的任何事件驱动模块(例如net)都扩展了一个名为EventEmitter的根类。

Node.js中的EventEmitter有两种基本方法:on和emit。

考虑以下简单的 HTTP 服务器:

const net = require("net");  const server = net.createServer().listen(8081, "127.0.0.1");  server.on("listening", function () {   console.log("Server listening!"); });  server.on("connection", function (socket) {   console.log("Client connected!");   socket.end("Hello client!"); });

这里我们来听两个事件:listening 和connection。除了这些事件之外,event emitters 还公开一个 error  事件,以防发生错误。

如果在端口80上运行这段代码,而不是在前面的示例上侦听,将会得到一个异常:

const net = require("net");  const server = net.createServer().listen(80, "127.0.0.1");  server.on("listening", function () {   console.log("Server listening!"); });  server.on("connection", function (socket) {   console.log("Client connected!");   socket.end("Hello client!"); });

输出:

events.js:291       throw er; // Unhandled 'error' event       ^  Error: listen EACCES: permission denied 127.0.0.1:80 Emitted 'error' event on Server instance at: ...

要捕获它,我们可以注册一个error事件处理程序:

server.on("error", function(error) {   console.error(error.message); });

输出结果:

listen EACCES: permission denied 127.0.0.1:80

关于 JavaScript中怎么实现错误处理问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript中怎么实现错误处理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

React中Portals与错误边界处理怎么实现

这篇“React中Portals与错误边界处理怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“React中Portal
2023-06-05

SQL Server中如何实现错误处理

今天小编给大家分享一下SQL Server中如何实现错误处理的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、SQLServ
2023-06-30

驯服 JavaScript 错误对象:错误处理的最佳实践

处理 JavaScript 错误对象是一项关键任务,可以增强应用程序的健壮性和用户体验。遵循最佳实践对于有效管理错误并提供有意义的反馈至关重要。
驯服 JavaScript 错误对象:错误处理的最佳实践
2024-03-05

怎么处理VSFTPD实验500OOPS错误

小编给大家分享一下怎么处理VSFTPD实验500OOPS错误,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vsftpd用了有一年了,发现个VSFTPD的错误,一直
2023-06-16

Angular怎么实现错误处理和请求拦截

本篇内容主要讲解“Angular怎么实现错误处理和请求拦截”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Angular怎么实现错误处理和请求拦截”吧!基本使用用 Angular 提供的 Http
2023-07-04

JavaScript中的异常处理怎么实现

这篇“JavaScript中的异常处理怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript中的异常处理
2023-06-30

JavaScript错误处理的10个最佳实践

JavaScript错误处理是开发人员日常工作中不可或缺的一部分。处理错误可以帮助开发人员识别和解决代码中的问题,提高应用程序的稳定性和可靠性。
JavaScript错误处理的10个最佳实践
2024-02-27

如何在JavaScript中优雅地处理错误

在JavaScript中优雅地处理错误可以让你的代码更加健壮和可靠。本文将介绍几种处理错误的常用方法,以及如何使用它们来提高代码的质量和可维护性。 JavaScript 错误处理 异常处理 try catch finally throw
如何在JavaScript中优雅地处理错误
2024-02-27

Spring Cloud gateway自定义错误处理Handler怎么实现

本文小编为大家详细介绍“Spring Cloud gateway自定义错误处理Handler怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring Cloud gateway自定义错误处理Handler怎么实现”文章能帮助大家
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录