JavaScript异步编程4——Promise错误处理

charlee44 2021-05-04 12:06:47
编程 javascript promise 异步 错误处理


1. 概述

在上一篇文章《JavaScript异步编程3——Promise的链式使用》中,通过Promise的链式使用,避免程序中多次嵌套回调(回调地狱)。根据前面的文章我们可以知道,Promise是基于状态的,成功/失败的状态会分别去处理相应的回调函数。一般而言,失败的状态我们希望能够捕获它,将它像异常(Error)一样处理。

2. 详论

Promise的then()方法有两个参数,一个是成功的回调函数,一个是失败的回调函数。可以将失败的回调函数这个参数省略掉,而使用Promise的catch()方法,捕获失败的异常。例如,我们把上一篇文章中的例子改进一下:

$(function () {
function get(url) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
//即使是404也会进入这个相应函数,所以需要检测状态
if (req.status == 200) {
//完成许诺,返回响应文本
resolve(req.response);
} else {
//完成未完成,返回错误
reject(Error(req.statusText));
}
};
// 发生错误时的相应函数
req.onerror = function () {
reject(Error("Network Error"));
};
// 发送请求
req.send();
});
}
function getImg(uri){
return new Promise(function(resolve, reject){
var img = new Image();
img.onload = function () {
resolve(img);
};
img.onerror = function () {
reject(Error("Load Image Error!"));
}
img.src = uri;
});
}
var addressUri = "./1.json";
get(addressUri).then(function (response) {
var imgJson = JSON.parse(response);
return getImg(imgJson[0]);
}).catch(function (error) {
console.error("Failed!", error);
}).then(function(img){
$(img).appendTo($('#container'));
}).catch(function(error){
console.error("Failed!", error);
});
});

改进前与改进后的程序处理流程很相似,但是还是有细微的差别。前者通过Promise的then()处理异常,只会运行功能的回调函数和失败的回调函数其中的一个;后者通过catch()处理异常,则更加像JavaScript的try/catch,在try{}中发生的错误会立即转到catch{}块。这样的话,就很容易实现类似于try/catch异常操作的的非阻塞异步版本:

$(function () {
function get(url) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
//即使是404也会进入这个相应函数,所以需要检测状态
if (req.status == 200) {
//完成许诺,返回响应文本
resolve(req.response);
} else {
//完成未完成,返回错误
reject(Error(req.statusText));
}
};
// 发生错误时的相应函数
req.onerror = function () {
reject(Error("Network Error"));
};
// 发送请求
req.send();
});
}
function getImg(uri){
return new Promise(function(resolve, reject){
var img = new Image();
img.onload = function () {
resolve(img);
};
img.onerror = function () {
reject(Error("Load Image Error!"));
}
img.src = uri;
});
}
var addressUri = "./1.json";
get(addressUri).then(function (response) {
var imgJson = JSON.parse(response);
return getImg(imgJson[0]);
}).then(function(img){
$(img).appendTo($('#container'));
}).catch(function(error){
console.error("Failed!", error);
}).then(function(){
alert("图片加载完成!");
});
});

在上面这个改进的例子中,第一个then()和第二个then()中如果存在错误,就会将异常转到catch()中,而第三个then(),则是程序无论如何都会往下继续运行的。

3. 参考

  1. JavaScript Promises: An introduction
版权声明
本文为[charlee44]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/charlee44/p/14729077.html

  1. Spring 3中异步方法调用
  2. AOP相关讨论
  3. jf能支持的表现层目前只有struts 1.x么?
  4. 在j2ee中实现一般java对象数据库的方法。
  5. FTP connecting windows and Linux
  6. Decorator design pattern - gene zeiniss
  7. Asynchronous method call in spring 3
  8. Discussion on AOP
  9. Is struts 1. X the only presentation layer supported by JF?
  10. The method of realizing general Java object database in J2EE.
  11. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  12. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  13. MySQL 的 in 查询不走索引?我拿什么拯救你!
  14. MySQL in query does not go index? What can I do to save you!
  15. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  16. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  17. Java小白入门必学!最全数据类型和运算符笔记,附实例
  18. Java Xiaobai introduction must learn! Notes on the most complete data types and operators, with examples
  19. Spring MVC请求与响应
  20. Spring MVC request and response
  21. Java 11已经不再完全免费,不要陷入Oracle的Java 11陷阱
  22. Vue.js比jQuery更容易学习
  23. 启动/删除Docker容器时出现问题 - 如何修复
  24. eclipse run on server时出现了错误信息.求急!!
  25. 请教高手一个关于lunce的问题:java.io.IOException: Cannot rename ...\segments.new
  26. Java 11 is no longer completely free. Don't fall into the Java 11 trap of Oracle
  27. Vue. JS is easier to learn than jQuery
  28. Problem starting / deleting docker container - how to fix it
  29. There is an error message in eclipse run on server!!
  30. Ask a question about lunce: java.io.ioexception: cannot rename... \ segments.new
  31. 从零搭建Spring Boot脚手架(2):集成mybatis
  32. 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper
  33. 只知道java反射,宁知道内省吗?
  34. Build spring boot scaffold from scratch (2): integrate mybatis
  35. Build spring boot scaffold from scratch (4): handwritten mybatis general mapper
  36. Do you prefer introspection to reflection?
  37. ASP调用SDK微信分享好友、朋友圈
  38. ASP calls SDK wechat to share friends and circle of friends
  39. BAT 必问的 MySQL 面试题你都会吗?
  40. Do you know all the MySQL interview questions that bat must ask?
  41. ASP调用SDK微信分享好友、朋友圈
  42. ASP calls SDK wechat to share friends and circle of friends
  43. SpringCloud(六)Bus消息总线
  44. 详解JavaScript中的正则表达式
  45. Springcloud (6) bus message bus
  46. Explain regular expressions in JavaScript
  47. Java 响应式关系数据库连接了解一下
  48. Java14它真的来了, 真是尾气都吃不到了
  49. 视频:使用Docker搭建RabbitMQ环境
  50. Java responsive relational database connection
  51. Java14 it's really coming. I can't eat the exhaust
  52. Video: building rabbitmq environment with docker
  53. SpringCloud(六)Bus消息总线
  54. 详解JavaScript中的正则表达式
  55. Springcloud (6) bus message bus
  56. Explain regular expressions in JavaScript
  57. Docker实战:用docker-compose搭建Laravel开发环境
  58. Docker: building laravel development environment with docker compose
  59. 求助,JAVA如何获取系统当前所有进程
  60. 有人用过JMeter或用HttpUnit写过测试吗????