promise实现-1:错误处理

promise用了挺长时间, 感觉这玩意都能算是个常用设计模式了
不过还是有些地方比较迷糊, 打算自己从头实现一个 梳理一下

promise异常处理

使用时候最晕的就是异常处理的流程, 转载一个:
catch是then(undefined, func)的语法糖,
对于 then(func1, func2) 来说,必会调用 func1 或 func2 之一,但绝不会两个都调用。
而 then(func1).catch(func2) 这样,如果 func1 返回否定的话 func2 也会被调用,因为他们是链式调用中独立的两个步骤。

例子1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
asyncThing1().then(function() {
return asyncThing2();
}).then(function() {
return asyncThing3();
}).catch(function(err) {
return asyncRecovery1();
}).then(function() {
return asyncThing4();
}, function(err) {
return asyncRecovery2();
}).catch(function(err) {
console.log("Don't worry about it");
}).then(function() {
console.log("All done!");
});

例子2

1
2
3
4
5
6
7
8
9
10
11
12
13
//步骤1
getJSON('story.json').then(function(story) {
return getJSON(story.chapterUrls[0]);//步骤2
}).then(function(chapter1) {
//正确处理
addHtmlToPage(chapter1.html);
}).catch(function() {
//错误处理
addTextToPage("Failed to show chapter");
}).then(function() {
//正确或错误后, 总要调用
document.querySelector('.spinner').style.display = 'none';
});

上面的代码就是下面这段的非阻塞异步版:

1
2
3
4
5
6
7
8
9
10
try {
var story = getJSONSync('story.json');
var chapter1 = getJSONSync(story.chapterUrls[0]);
addHtmlToPage(chapter1.html);
}
catch (e) {
addTextToPage("Failed to show chapter");
}
document.querySelector('.spinner').style.display = 'none';

例子3 all的错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
getJSON('story.json').then(function(story) {
addHtmlToPage(story.heading);
// 接受一个 Promise 数组并等待他们全部完成
return Promise.all(
// 把章节 URL 数组转换成对应的 Promise 数组
story.chapterUrls.map(getJSON)
);
}).then(function(chapters) {
// 现在我们有了顺序的章节 JSON,遍历它们……
chapters.forEach(function(chapter) {
// ……并添加到页面中
addHtmlToPage(chapter.html);
});
addTextToPage("All done");
}).catch(function(err) {
// 捕获过程中的任何错误
addTextToPage("Argh, broken: " + err.message);
}).then(function() {
document.querySelector('.spinner').style.display = 'none';
});

then队列

如果想要实现then队列

1
2
3
fun.then(function(){
return //thenable
})

里边要明确的return一个thenable对象:

1
2
如果你返回一个值,它就会被传给下一个“then”的回调;
而如果你返回一个“类 Promise”的对象,则下一个“then”就会等待这个 Promise 明确结束(成功/失败)才会执行

所以要是忘了return //thenable, 就相当于是返回了一个值(undefined)