- 内容简介
- 译者序
- 前言
- 第 1 章 安装配置新项目
- 第 2 章 Flexbox 布局介绍
- 第 3 章 用 React Native 开发一个应用
- 第 4 章 在 React Native 中使用导航
- 第 5 章 动画和滑动菜单
- 第 6 章 用 React Native 绘制 Canvas
- 第 7 章 使用 React Native 播放音频
- 第 8 章 你的第一个自定义视图
- 第 9 章 Flux 介绍
- 第 10 章 处理复杂的应用程序状态
- 第 11 章 使用 Node 来实现服务端 API
- 第 12 章 在 React Native 中使用文件上传
- 第 13 章 理解 JavaScript Promise
- 第 14 章 fetch 简介
- 第 15 章 在 iOS 中使用 SQLite
- 第 16 章 集成 Google Admob
- 第 17 章 React Native 组件国际化
- 附录 A React.js 快速介绍
- 附录 B Objective-C Primer
- 附录 C webpack 入门
链式调用
“then”函数还有更加巧妙的用法,你可以将修改数值或者添加异步操作的“then”方法串联起来调用,从而让它们按顺序执行。
数值处理
可以简单修改一下原值,然后返回修改结果:
var promise = new Promise(function(resolve, reject) {
resolve(1);
});
promise.then(function(val) {
console.log(val); // 1
return val + 2;
}).then(function(val) {
console.log(val); // 3
});
我们回到上文的代码继续:
get('story.json').then(function(response) {
console.log("Success! ", response);
});
我们期望参数 response 是 JSON 格式的数据,但是这里接收到的是纯文本格式。当然,我们可以在 get 函数中修改服务器的响应格式为 JSON,但是也可以在 Promise 代码中做修改来达到相同目的:
get('story.json').then(function(response) {
return JSON.parse(response);
}).then(function(response) {
console.log("Yey JSON! ", response);
});
JSON.parse 函数只接受一个参数,并返回转换后的结果。我们根据这个特性来简化一下代码:
get('story.json').then(JSON.parse).then(function(response) {
console.log("Yey JSON! ", response);
});
可以在开发者工具中的控制台下看到相应的请求结果。其实,我们也可以简单地写一个 getJSON 方法:
function getJSON(url) {
return get(url).then(JSON.parse);
}
异步操作队列
你可以通过串联“then”方法来依次执行异步操作。
当在“then”方法的回调函数里有返回值的时候,这里有些重要的事情需要我们关注。如果你返回的是一个值,那么下一个“then”会被立即调用,并把这个值传递给它的回调函数。如果你返回的是一个“类 Promise”对象,那么下一个“then”方法会等待执行,直到这个 Promise 被解决(成功或者失败)后才执行。举个例子:
getJSON('story.json').then(function(story) {
return getJSON(story.chapterUrls[0]);
}).then(function(chapter1) {
console.log("Got chapter 1! ", chapter1);
});
这里我们对“story.json”发出了一个请求,它会返回一些异步请求的 URL 地址,然后我们又对第一个地址进行了异步请求。现在同简单的事件回调模式相比,Promise 开始显示出自己的优势了。可以像下面这样写个获取章节内容的函数:
var storyPromise;
function getChapter(i) {
storyPromise = storyPromise || getJSON('story.json');
return storyPromise.then(function(story) {
return getJSON(story.chapterUrls[i]);
})
}
// 使用它很简单
getChapter(0).then(function(chapter) {
console.log(chapter);
return getChapter(1);
}).then(function(chapter) {
console.log(chapter);
});
我们一开始并不请求“story.json”,直到第一次调用 getChapter 方法时才请求,但是后面再调用该方法时会重用已有的 story Promise。因此,story.json 只请求了一次。这大大提高了效率, Promise 真是太棒了!
错误处理
如上文所述,我们知道“then”方法有两个参数,一个是成功后的回调函数,一个是失败后的回调函数(用 Promise 的术语来说,就是 resolve 或者 reject):
get('story.json').then(function(response) {
console.log("Success! ", response);
}, function(error) {
console.log("Failed! ", error);
});
你也可以使用“catch”方法:
get('story.json').then(function(response) {
console.log("Success! ", response);
}).catch(function(error) {
console.log("Failed! ", error);
});
其实“catch”方法并没有什么特别的地方,它只是 then(undefined, func) 形式的一种语法糖而已,但是它的可读性很好。要注意上面两个例子的表现行为并不一致,后者等同于下面这段代码:
get('story.json').then(function(response) {
console.log("Success! ", response);
}).then(undefined, function(error) {
console.log("Failed! ", error);
});
语法差别虽然不大,但是意义重大。Promise 被 reject 后会直接跳转到之后第一个配置了 reject 回调的 then 方法(或者是“catch”方法,二者等价)中。对于 then(func1, func2),只会调用 func1 或 func2 中的一个回调,绝不会两个都被调用。但是 then(func1).catch(func2) 这种形式就不同了,当 func1 中返回 reject 时,func2 也会被调用,这是因为它们分别处于链式调用的不同步骤。请看下面的代码:
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! ");
});
上面的流程非常类似于 JavaScript 中的 try/catch 语句,在“try”代码块中发生的错误会立即跳转到“catch”的代码块中。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论