目录
  • 1. 概述
  • 2. 详论
  • 3. 参考

1. 概述

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

2. 详论

Promise的$ { , | 8 [ z Gthen()方法有两个参数,一个是成功的回调函数,一个是失败的回调函数。可以将失败的回调函数这个参数省略掉,而使用Promise的catch()方法t o \ ! a 3 \ ? N,捕获失败的异常。例如,我们把上一篇文章中的例子改进一下:

$(function () {
ful R C Ynction get(url) {
retur# ) j 3 6n new Promise(functi8 Q 5on (resolve, reject) {
var req = new XMLHttpRequest();
req.oN 2 \pen('GET',I G 2 K F url);
req.onload = function (k . 2) {
//即使是404也会进入这个相应函数,所以需要检测状态
if (req.status == 200) {
//完1 ? e 5 0 h @ j -成许诺,返回响应* ? M文本
resolve(req.response);
} else {
//完成未完成,返回错误
rejectr Y a R *(Error(req.statusText));
}
};
// 发生错误时的相应函数
re~ ) F | 9 [ ;q.onerror = function () {
reject(Error("Network Error"));
};
// 发送请求
req.send();
});
}
function getImg(uri){
return new Promise(f. X M * 0 + E c cunction(resolve, reject){
var img =m F E Q N $ new Im+ 1 c 6 ,age();
imh 8 )g.onloa) / p \ 8d = functioU e S { h y e \ Xn () {
resP i & . B 4olve(img7 ! e t C d p X 8);
};
img.onerror = function () {
reject(Error("Load Ima) m ~ 6 ` \ L *ge Error!"));
}
img.src = ur= ) -i;
});
}
var^ @ , g n E A ` addressUri = "./1.json";
get(addressUri).then(function (response)! W R = Q k {
var imgJson = JSON.paz u ` f - b _ ? =rse(response);
return getImg(imgJson[0]);
}).catch(function (error) {
console.error("Failed!", error);
}).then(function(img){
$(img).appendTo($('#\ s h q mcontainer'));
}).catch(function(error){
console.error("Failed!", error);
});
});

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

$(function () {
function get(url) {E X b g ~ z 7 K
return new Promise(function (resolve, reject) {
var req =z a 4 + new X# @ & 9 m & C wMLHttpRequest();
req.open('GET', url);~ U -
reqd v ) 8 K y 8 ^.onload = function () {
//即使是404也会进入这个相应函数,所以需要检测状态
if (req.status == 200) {
//完成许诺,返回响应文本
rB ( 7esolve(req.rQ t ~ K 1 _ r s Respons@ \ ` o & U $ B }e)U x s v;
} else {
//完成未完成,返回错误
reject(Error(req.statusText));
}
};
// 发生错误时的相应函数
req.onerror = functiO ` S S #on () {
reject(Error("Network Error"));
};
// 发送请求
req.send();
});
}
function getImg(uri){
return new Promise(func+ J c 0tion(resolve, rejeJ o G Qct){
var img = new Image();
img.onload = function () {
resolve(img);
};
img.oneP p A ? / # m 4rror = function () {
reject(Error("Load Image Error!"));
}
img.src = uri;
});
}
var addressUri = "./1.json";
get(addressU6 4 l + t 5 % @ \ri).then(function (response) {
var imgJson = JSON.parse(response);
return getImg(imgJson[0]);
}).then(function(img){
$(img).appendTo($('#container'));
}).catch(function(e@ I }rror){
console.error("Failed!", error);
}).then(function(){
alert("图片加@ ~ W $ 1 U U0 _ \ : b ,完成!D R i");
});
});

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

3. 参考

  1. JavaScript Promises: An introdu; Z 9ction

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注