浅谈ECMAScript 6下的promises API
9.2. 构造函数
- var p = new Promise(executor(resolve, reject));
9.3. 静态方法
9.4. 继承原型方法
- function defaultOnFulfilled(x){
- return x;
- }
- function defaultOnRejected(e){
- throw e;
- }
10. promises 的优势与劣势
10.1. 优势
- fetch(url)
- .then(request => request.text())
- .then(str => ...)
- System.import('some_modle.js')
- .then(some_module => {
- ...
- })
- fs.readFile(name, opts?, function(err, data))
- readFilePromisified(name, opts?)
- .then(dataHandler, errorHandler)
此外,promises 的优势还包括更好的错误处理机制(异常的集成)和组合更任意更容易(因为你可以使用一些同步的工具,比如 Array.prototype.map())。
10.2. 劣势
11. promises 与 生成器
- Q.spawn(function* () {
- try {
- let [foo, bar] = yield Promise.all([ // (A)
- httpGet('foo.json'),
- httpGet('bar.json')
- ]);
- render(foo);
- render(bar);
- } catch (e){
- console.log('Read failed: '+ e );
- }
- });
- asyc function(){
- try {
- let [foo, bar] = await Promise.all([
- httpGet('foo.json'),
- httpGet('bar.json')
- ]);
- render(foo);
- render(bar);
- } catch (e){
- console.log('Read failed: '+ e );
- }
- }
12. 调试 promises
- function first(){
- setTimeout(function () { second('a') }, 0); //(A)
- }
- function second(){
- setTimeout(function () { third('b') }, 0); //(B)
- }
- function third(){
- debugger;
- }
- first();
正如截图中所示,调试器展现一个包含三个函数的跟踪堆栈。它包含了 line A 和 line B 处的异步函数。
13. promises 内部窥秘
13.1 一个独立的 promise
- var dp = new DemoPromise();
- dp.resolve('abc');
- dp.then(function(value){
- console.log(value); // abc
- });
- DemoPromise.prototype.then = function (onFulfilled, onRejected) {
- var self = this;
- var fulfilledTask = function () {
- onFulfilled(self.promiseResult);
- };
- var rejectedTask = function () {
- onRejected(self.promiseResult);
- };
- switch (this.promiseState) {
- case 'pending':
- this.fulfillReactions.push(fulfilledTask);
- this.rejectReactions.push(rejectedTask);
- break;
- case 'fulfilled':
- addToTaskQueue(fulfilledTask);
- break;
- case 'rejected':
- addToTaskQueue(rejectedTask);
- break;
- }
- };
- function addToTaskQueue(task) {
- setTimeout(task, 0);
- }
- Promise.prototype.resolve = function (value) {
- // 为执行回调函数方法 如果不为状态 pending 为在 then 时刻已经处理执行过,立即跳出
- if (this.promiseState !== 'pending') return;
- this.promiseState = 'fulfilled';
- this.promiseResult = value;
- this._clearAndEnqueueReactions(this.fulfillReactions);
- return this; // 链式
- };
- Promise.prototype._clearAndEnqueueReactions = function (reactions) {
- this.fulfillReactions = undefined;
- this.rejectReactions = undefined;
- reactions.map(addToTaskQueue);
- };
13.2 链式(注意,这部分已经为下一步扁平化做好了基础)
- DemoPromise.prototype.then = function (onFulfilled, onRejected) {
- var returnValue = new DemoPromise(); // (A)
- var self = this;
- var fulfilledTask;
- if (typeof onFulfilled === 'function') {
- fulfilledTask = function () {
- var r = onFulfilled(self.promiseResult);
- returnValue.resolve(r); // (B)
- };
- } else {
- fulfilledTask = function () {
- returnValue.resolve(self.promiseResult); // (C)
- };
- }
- var rejectedTask;
- if (typeof onRejected === 'function') {
- rejectedTask = function () {
- var r = onRejected(self.promiseResult);
- returnValue.resolve(r); // (D)
- };
- } else {
- rejectedTask = function () {
- // Important: we must reject here!
- // Normally, result of `onRejected` is used to resolve
- returnValue.reject(self.promiseResult); // (E)
- };
- }
- ...
- return returnValue; // (F)
- };
13.3 扁平化
扁平化思想主要是使链式方式更为便捷:一般,将一个 reaction 返回的值传递到下一个 then()。如果我们返回一个 promise,不包裹的形式是最好的,像下面的例子:
- asyncFunc1()
- .then(function (value1){
- return asyncFunc2(); // A
- })
- .then(function (value2){
- // value2 为 asyncFunc2() promise 的通过状态。
- console.log(value2);
- });
- DemoPromise.prototype.resolve = function (value) {
- if (this.alreadyResolved) return;
- this.alreadyResolved = true;
- this._doResolve(value);
- return this; // enable chaining
- };
- DemoPromise.prototype._doResolve = function (value) {
- var self = this;
- // Is `value` a thenable?
- if (value !== null && typeof value === 'object'
- && 'then' in value) {
- addToTaskQueue(function () { // (A)
- value.then(
- function onFulfilled(value) {
- self._doResolve(value);
- },
- function onRejected(reason) {
- self._doReject(reason);
- });
- });
- } else {
- this.promiseState = 'fulfilled';
- this.promiseResult = value;
- this._clearAndEnqueueReactions(this.fulfillReactions);
- }
- };
13.4. 更详细的 Promise 状态
13.5. 异常
- var fulfilledTask;
- if (typeof onFulfilled === 'function') {
- fulfilledTask = function () {
- try {
- var r = onFulfilled(self.promiseResult); // (A)
- returnValue.resolve(r);
- } catch (e) {
- returnValue.reject(e);
- }
- };
- } else {
- fulfilledTask = function () {
- returnValue.resolve(self.promiseResult);
- };
- }
13.6. 揭示构造函数模式
14. 两个常用的 promise 附加方法
14.1. done()
- function doSomeThing(){
- asyncFunc()
- .then(f1)
- .catch(r1)
- .then(f2); // A
- }
- function doSomeThing(){
- asyncFunc()
- .then(f1)
- .catch(r1)
- .done(f2);
- }
又或者仅仅是插到最后一个 then() 之后(无参数):
- function doSomeThing(){
- asyncFunc()
- .then(f1)
- .catch(r1)
- .then(f2)
- .done();
- }
- Promise.prototype.done = function(onFulfilled, onRejected){
- this.then(onFulfilled, onRejected)
- .catch(function(reason){
- setTimeout( ()=>{ throw reason }, 0 );
- });
- };
14.2. finally()
- createPeaource(...)
- .then(function(value1){ ... })
- .then(function(value2){ ... })
- .finally(function(){ ... });
- Promise.prototype.finally = function (callback) {
- let p = this.constructor;
- // 不在此调用回调函数,
- // 希望使用 then 来处理
- return this.then(
- // Callback fulfills: 传递参数结果
- // Callback rejects: 传递拒绝状态
- value => p.resolve(callback()).then(() => value),
- reason => p.resolve(callback()).then(() => { throw reason })
- );
- };
- showSpinner();
- fetchGalleryData()
- .then(data => updateGallery(data) )
- .catch(showNoDataError)
- .finnally(hideSpinner);
- var HTTP = require('q-io/http');
- var server = HTTP.Server(app);
- return server.listen(0)
- .then(function(){ ... })
- finally(server.stop);
15. ES6 兼容的 promise 库
下面有一些 promise 的库,有一些 ES6 的API,意味着你在将来也可以用原生 ES6 代码替换。
16. 传统的异步代码的接口
放你使用一个 promsie 库时,有时是基于不支持 promsie 的异步代码。这段讲述一下 Node.js 风格的异步函数与 jQuery deferreds。
16.1 Node.js 的接口
- var readFile = Q.denideify( FS.readFile );
- readFile('foo,txt', 'utf-8')
- .then(function(text){
- ....
- });
16.2. jQuery 的接口
- Promise.resolve(
- jQuery.ajax({...})
- ).then(funciton(data){
- console.log(data);
- }).catch(function(reason){
- console.error(reason)
- });
17. 延伸阅读
1. Promises/A+(http://promisesaplus.com/):Brian Cavalier 与 Domenic Denicola 编辑(JS promise 事实标准)
浅谈ECMAScript 6下的promises API相关推荐
- 浅谈虚拟化技术下的云安全如何处置
浅谈虚拟化技术下的云安全如何处置 近年来,云计算是目前非常热门的一个研究领域,其实它并不是一种全新的技术,而是许多技术的融合体,包括分布式计算.动态和拓展等各种各样的技术算法,而虚拟化技术是云计算里最 ...
- 计算机辅助审计的特点是,浅谈新环境下计算机辅助审计的特点和应用_1
浅谈新环境下计算机辅助审计的特点和应用_1 (7页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 24.90 积分 从本学科出发,应着重选对国民经济具有一定 ...
- css中字体下划线样式,css下划线 浅谈css自定义下划线
使用css样式对一段文字或一段文字中其中几个文字设置虚线效果的下划线如何实现?我们知道css字体下划线使用text-decoration样式实现,而虚线下划线则不能使用此css样式属性.要实现通过下边 ...
- 浅谈全局视角下的设计模式
写在前面: 以下内容,更多的是自己的思考总结,不可避免出现有争议的地方,请谨慎食用. 浅谈全局视角下的设计模式 1.业务开发经常使用的设计模式有哪些? 2.为什么有些设计模式不常见呢? 3.为什么这些 ...
- 浅谈互联网时代下融媒技术现状
浅谈互联网时代下融媒技术现状 摘要:近年来,我国数字技术的迅速发展使得媒体技术在"互联网+"时代下不断发展融合,形成了如今的融合媒体技术.新兴融媒技术的发展给广播电视行业带来了新的 ...
- 浅谈上、下拉电阻的作用
浅谈上.下拉电阻的作用 上下拉电阻: 1.当TTL电路驱动COMS电路时,如果TTL电路输出的高电平低于CMOS电路的最低高电平(一般为3.5V),这时就需要在TTL的输出端接上拉电阻,以提高输出高电 ...
- java的向下转型_浅谈Java向下转型的意义
一开始学习 Java 时不重视向下转型.一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型. 其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向 ...
- 浅谈 TypeScript【下】-- TypeScript 语言规范与基本应用
文章内容输出来源:拉勾教育 大前端高薪训练营 前言 在 [浅谈 TypeScript[上]]中,简单讲述了关于JavaScript静态类型检查工具Flow的用法等.可以看到,我们接下来讲述的TypeS ...
- 跑三小时的monkey测试该怎么算_浅谈App测试(下)~带音频
文 | Vicky 采编|Emily 浅谈App测试(上)-带音频 一.功能测试 二.性能测试 (1)耗电量 影响因素:定位.传感器.蓝牙,其中CPU.持续定位是两个平台造成耗电的主要因素. (2) ...
最新文章
- mingw编译boost_1_66_0
- 深入理解RocketMQ是如何做到高性能的?
- mysql 去重后拼接_mysql学习笔记(三)—— 查询select
- BZOJ 2186 SDOI2008 沙拉公主的困惑 数论
- java countdowntimer_(六)Android中使用CountDownTimer实现倒计时功能
- ajax无法访问,Ajax不能跨域访问的解决方案
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_5_flush方法和close方法的区别...
- Yanobox Moods for mac(FCPX/AE/PR滤镜插件)激活版
- 单片机12864带字库汇编使用教程
- 假设某台台式计算机的内存储器容量为128,假设某台式计算机的内存储器容量为128MB,硬盘容量为10GB。硬盘的容量是内存容量的60倍。...
- 1818. 绝对差值和
- nginx php 后缀名,nginx如何隐藏后缀名php
- 创业者两大特征:喜欢折腾与坚持不懈
- 那些选择网络工程的女生们,后来都怎么样了?
- 【GTASA】如何解锁Locked的DFF模型
- 计算机考试设置背景音乐,给Excel表格添加背景音乐
- 使用 eBPF 和 XDP 高速处理数据包
- VB语音对接验证码短信接口DEMO示例
- Java数据结构与算法——线性查找 二分查找 插值查找
- android 软键盘弹出 布局上移动
热门文章
- Javascript 数组求和的方法
- 一款基于Uniapp开发的开源低代码平台
- minicom指令_串口调试利器--Minicom配置及使用详解
- R语言error in diff.default(xscale) : 无法弹到最上层的視窗(‘grid‘和‘graphics‘输出有混合?)错误: VECTOR_ELT() can only be
- 使用宝塔面板搭建 WordPress 站点
- 哪些蓝牙耳机防水性强?防水蓝牙耳机推荐
- stm32 例程中lcd颜色初始化显示
- dw如何上传文件到本地服务器,dw如何上传到远程服务器
- 保证分布式系统数据一致性的6种方案
- 贝叶斯网络,看完这篇我终于理解了!