- 内容简介
- 译者序
- 前言
- 第 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”的代码块中。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论