JavaScript异步编程4——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. 参考
JavaScript异步编程4——Promise错误处理的更多相关文章
- javascript异步编程,promise概念
javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...
- Javascript异步编程之三Promise: 像堆积木一样组织你的异步流程
这篇有点长,不过干货挺多,既分析promise的原理,也包含一些最佳实践,亮点在最后:) 还记得上一节讲回调函数的时候,第一件事就提到了异步函数不能用return返回值,其原因就是在return语句执 ...
- JavaScript异步编程的Promise模式(转)
异步模式在web编程中变得越来越重要,对于web主流语言Javascript来说,这种模式实现起来不是很利索,为此,许多Javascript库(比如 jQuery和Dojo)添加了一种称为promis ...
- JavaScript异步编程的Promise模式
参考: http://www.infoq.com/cn/news/2011/09/js-promise http://www.cnblogs.com/rubylouvre/p/3495286.html ...
- JavaScript异步编程原理
众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...
- 深入解析Javascript异步编程
这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...
- JavaScript 异步编程的前世今生(上)
前言 提到 JavaScript 异步编程,很多小伙伴都很迷茫,本人花费大约一周的业余时间来对 JS 异步做一个完整的总结,和各位同学共勉共进步! 目录 part1 基础部分 什么是异步 part2 ...
- Javascript异步编程之一异步原理
本系列的例子主要针对node.js环境,但浏览器端的原理应该也是类似的. 本人也是Javascript新手,把自己这段时间学习积累的要点总结下来,希望可以对同样在学习Javascript/node.j ...
- Javascript异步编程之二回调函数
上一节讲异步原理的时候基本上把回掉函数也捎带讲了一些,这节主要举几个例子来具体化一下.在开始之前,首先要明白一件事,在javascript里函数可以作为参数进行传递,这里涉及到高阶函数的概念,大家可以 ...
- 探索Javascript异步编程
异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显.许多不同的方法都可以解决这个问题,本文讨论了一些方法 ...
随机推荐
- 探究——C# .net 代码混淆/加壳
背景: 保密. 过程: 先查询一下常见的加壳工具: DotFuscator,官方自带,据说免费版混淆程度不高 Virbox Protector,很好很优秀,但是收费 NET Reactor,可能会被识 ...
- C#桶排序算法
前言 桶排序是一种线性时间复杂度的排序算法,它将待排序的数据分到有限数量的桶中,每个桶再进行单独排序,最后将所有桶中的数据按顺序依次取出,即可得到排序结果. 实现原理 首先根据待排序数据,确定需要的桶 ...
- windows开发环境备份,再也不怕重装系统了
每次重装系统后,都要重新安装软件,配置环境变量,极为繁琐.故作环境环境变量备份,常用软件恢复记录,前提是你的软件要安装在非系统盘,D/E盘等 软件安装在非系统盘 开发软件安装在非系统盘,建好目录.重装 ...
- CentOS7 Ceph分布式集群部署
CentOS 7 下安装Ceph-nautilus 本问主要记录在CentOS 7下如何安装Ceph-nautilus,安装过程中遇到的一些问题及解决方法. 1.Ceph实验准备 以下是本次实验所用到 ...
- Nginx-多功能脚本
#!/bin/bash #2020年2月16日 #auto_install_nginx_web.v3 #by fly ################################ #NGX_VER ...
- YXの每日挂分记录
7.11 T1 不开两倍数组 100->60. 7.18 T2 dp+矩乘 转移不判边界 100->10. 7.20 T2 人类智慧 1e6 n log n 100->10,求前 5 ...
- 2022-10-22 CSP赛前隔离时的模拟赛 2:3
T1 简单红题,不懈于写. 锐评:镜子反射出来的竟然没有镜像一下. T2 坑人东西调了 2h. 类似于 round1 的 T4. 线性 \(\Theta(n)\) 过. T3 T4 其实简单,负边权要 ...
- Golang 面向对象深入理解
1 封装 Java 中封装是基于类(Class),Golang 中封装是基于结构体(struct) Golang 的开发中经常直接将成员变量设置为大写使用,当然这样使用并不符合面向对象封装的思想. G ...
- c#中建造者设计模式详解
基础介绍: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 说白了就是将一个复杂的对象拆分成一个一个零件,然后按照既定顺序和规则进行组装,最终形成这个相对复杂的对象 ...
- QT(9)-QStyleOption及其子类
1 QStyleOption QStyleOption及其子类包含QStyle函数绘制图形元素所需的所有信息. 出于性能考虑,成员函数很少,对成员变量的访问是直接的(即使用.或者->运算符).这 ...