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

JavaScript异步编程4——Promise错误处理的更多相关文章

  1. javascript异步编程,promise概念

    javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...

  2. Javascript异步编程之三Promise: 像堆积木一样组织你的异步流程

    这篇有点长,不过干货挺多,既分析promise的原理,也包含一些最佳实践,亮点在最后:) 还记得上一节讲回调函数的时候,第一件事就提到了异步函数不能用return返回值,其原因就是在return语句执 ...

  3. JavaScript异步编程的Promise模式(转)

    异步模式在web编程中变得越来越重要,对于web主流语言Javascript来说,这种模式实现起来不是很利索,为此,许多Javascript库(比如 jQuery和Dojo)添加了一种称为promis ...

  4. JavaScript异步编程的Promise模式

    参考: http://www.infoq.com/cn/news/2011/09/js-promise http://www.cnblogs.com/rubylouvre/p/3495286.html ...

  5. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  6. 深入解析Javascript异步编程

    这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...

  7. JavaScript 异步编程的前世今生(上)

    前言 提到 JavaScript 异步编程,很多小伙伴都很迷茫,本人花费大约一周的业余时间来对 JS 异步做一个完整的总结,和各位同学共勉共进步! 目录 part1 基础部分 什么是异步 part2 ...

  8. Javascript异步编程之一异步原理

    本系列的例子主要针对node.js环境,但浏览器端的原理应该也是类似的. 本人也是Javascript新手,把自己这段时间学习积累的要点总结下来,希望可以对同样在学习Javascript/node.j ...

  9. Javascript异步编程之二回调函数

    上一节讲异步原理的时候基本上把回掉函数也捎带讲了一些,这节主要举几个例子来具体化一下.在开始之前,首先要明白一件事,在javascript里函数可以作为参数进行传递,这里涉及到高阶函数的概念,大家可以 ...

  10. 探索Javascript异步编程

    异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显.许多不同的方法都可以解决这个问题,本文讨论了一些方法 ...

随机推荐

  1. How to Install Python on Linux

    Summary Hostmonster uses the preinstalled version of Python that ships with CentOS. Because of this ...

  2. Qt OpenGL textures详解

    1. 初始化opengl资源 Q_INIT_RESOURCE:textures(资源名称) QSurfaceFormat:定义3d面显示方式 如果在vs+qt vs tools 中无法正常显示3d图形 ...

  3. meet

    以后就放弃csdn了,就来这里记录自己的成长,就当成一个树洞吧,开心与难过,学习与生活,进步与成长,留下时间的痕迹!冲!冲!冲!

  4. 浅析Redis大Key

    一.背景 在京东到家购物车系统中,用户基于门店能够对商品进行加车操作.用户与门店商品使用Redis的Hash类型存储,如下代码块所示.不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此 ...

  5. 如何通过Python代码旋转PDF页面

    前言 日常处理 PDF 文档时,我们时常会遇到页面颠倒.很难正常阅读或打印的情况. 在这种情况下,我们可以通过旋转页面来调整文档的方向.旋转时,也可以根据具体情况,选择顺时针或逆时针旋转特定的角度,以 ...

  6. 线程的查看方式&运行原理

    观察多个线程同时运行 主要是理解 交替执行 谁先谁后,不由我们控制 查看进程线程的方法 windows 任务管理器可以查看进程和线程数,也可以用来杀死进程 tasklist 查看进程 taskkill ...

  7. Grafana新手教程-实现仪表盘创建和告警推送

    前言 最近在使用Grafana的时候,发现Grafana功能比想象中要强大,除了配合Prometheus使用之外,他自身都可以做很多事情,可视化和监控平台,还可以直接根据用户自定义的告警规则完成告警和 ...

  8. Codeforces Round 905 (Div. 3)

    Codeforces Round 905 (Div. 3) A. Morning 题意:操作:显示,向前走都为一次操作:目标:显示这四个数 思路:0->10,然后依次作差就行 #include ...

  9. StackGres 1.6 数据库平台工程集群配置管理(K8S Pods/PostgreSQL/PgBouncer)

    Postgres 配置 PostgreSQL 的配置在 SGPostgresConfig CRD 中指定.如果在创建集群时没有指定自定义配置,StackGres 将创建一个默认配置,您可以在 这里 看 ...

  10. Windows服务器,通过Nginx部署VUE+Django前后端分离项目

    目录 基本说明 安装 Nginx 部署 VUE 前端 部署 Django 后端 Django admin 静态文件(CSS,JS等)丢失的问题 1. 基本说明 本文介绍了在 windows 服务器下, ...