- 内容简介
- 译者序
- 前言
- 第 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 入门
Promise 和 Generator
接下来的内容会涉及 ES6 的一些新特征,它对你在代码中使用 Promsie 会产生很大影响,但是不用担心,只需要把它们看做即将上映的大片预告即可。
ES6 给我们带来了 Generator,它允许函数在特定的位置像“return”一样退出,稍后又可以在这个特殊位置恢复先前状态继续执行:
function *addGenerator() {
var i = 0;
while (true) {
i += yield i;
}
}
注意函数名前的星号,这表明该函数是一个 Generator。关键字 yield 标记了暂停/恢复状态的特殊位置。我们可以像这样来使用:
var adder = addGenerator(); adder.next().value; // 0 adder.next(5).value; // 5 adder.next(5).value; // 10 adder.next(5).value; // 15 adder.next(50).value; // 65
但是,这些跟 Promise 有什么关系?其实,你可以用这种暂停/继续的机制写出形如同步(理解起来也简单),但是效果是异步的代码。你不必纠结于下面这个辅助函数中每行代码的具体含义,它让我们可以使用 yield 来等待其中 Promise 的完成:
function spawn(generatorFunc) {
function continuer(verb, arg) {
var result;
try {
result = generator[verb](arg);
} catch (err) {
return Promise.reject(err);
}
if (result.done) {
return result.value;
} else {
return Promise.resolve(result.value).then(onFulfilled,
onRejected);
}
}
var generator = generatorFunc();
var onFulfilled = continuer.bind(continuer, "next");
var onRejected = continuer.bind(continuer, "throw");
return onFulfilled();
}
这段代码从 Q 中引用而来,只是被改成了 JavaScript Promise 的形式。我们把上面最终的示例代码同 ES6 的一些特性结合改造后,产生了下面的代码:
spawn(function *() {
try {
// 'yield' 执行一个异步的等待,
// 返回这个
Promise 的结果
let story = yield getJSON('story.json');
addHtmlToPage(story.heading);
// 把章节
url 数组转换成对应的
Promise 数组
// 保证所有内容并行加载
let chapterPromises = story.chapterUrls.map(getJSON);
for (let chapterPromise of chapterPromises) {
// 等待每一章节加载完毕,将内容添加到页面上
let chapter = yield chapterPromise;
addHtmlToPage(chapter.html);
}
addTextToPage("All done");
}
catch (err) {
// 使用
try/catch 即可,否定的
Promise 会在这里被抛出
addTextToPage("Argh, broken: " + err.message);
}
document.querySelector('.spinner').style.display = 'none';
});
这同前文例子的功能完全一样,但是更加容易理解。这个例子目前可以在 Chrome 和 Opera 下运行,但是你需要先在 about:flags 中开启 Enable experimental JavaScript 的选项。
这里使用了一堆 ES6 的新语法:Promise、Generator、let、for-of。当我们在一个 Promise 上使用 yield 时,spawn 函数会等待 Promise 的完成,然后返回最终的结果值。如果 Promise 被 reject,则 spawn 中的 yield 会抛出一个异常,同时我们会用正常的 JavaScript try/catch 将其捕获后进行处理。天哪,这样写异步代码真是太简单了!
这种编程模式非常有用,它会在 ES7 中以异步函数的形式来体现,实现方式同上面的代码非常相似,只是不再需要 spawn 方法来辅助实现了。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论