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