es6中的promise解读
目录
- 什么是promise?
- promise的优点
- 回调地狱问题
- Promise的三种状态
- 一个简单的promise
- promise中的then
- 利用promise解决回调地狱
- promise的链式调用
- Promise.all()
- Promise.race()
- Promise.resolve()
- Promise.reject()
什么是promise?
简单的说它是一个异步流程的控制手段。是一个代表了异步操作最终完成或者失败的对象。
promise的优点
- promise解决了回调地狱的问题
- promise可以支持多个并发的请求
- promise的错误传播机制可以统一的处理错误信息
回调地狱问题
在传统的ajax调用过程中,下面以jquery.ajax为例。如果需求中要多次进行ajax交互,并且上一次的返回结果还要被下一次的ajax使用,代码基本上会变成:
$.ajax({type: "POST",url: "some.php",data: "name=John&location=Boston",success: function(msg){$.ajax({type: "POST",url: "some.php",data: msg,success: function(msg2){...//多次调用}});}
});
现在还只是两次调用关系,如果是多次调用将会引发下面的问题
- 多次调用不利于代码的管理于维护
- 发生错误时不能及时准备的定位错误位置
- 只要又一次不成功就不能进行下面的逻辑,不方便进行错误处理。
promise的链式调用就很好的解决了这个问题
Promise的三种状态
- Pending Promise对象实例创建时候的初始状态
- resolve 可以理解为成功的状态
- Reject 可以理解为失败的状态
promise 中的状态只能是从等待状态转换到成功状态或者失败状态,且状态转变之后不可逆。
一个简单的promise
let p = new Promise((resolve, reject) => {console.log(1)
});
console.log(2)
//1 2
promise里面只接受一个参数,叫做执行器函数,这个函数会同步执行。也就是说上面代码中的箭头函数被同步执行,得到的结果也就是1和2
promise中的then
每一个promise的实例上都有一个then方法,这个方法上有两个参数,一个是成功的回调,一个是失败的回调。而取决于成功或者失败的是promise的执行器函数中执行的是成功还是失败。
let p = new Promise((resolve, reject) => {console.log(1);resolve();//调用resolve会走到then的成功回调//reject();//调用resolve会走到then的失败回调
});
p.then(() => {console.log('成功')}, () => {console.log('失败')})//1 成功
如果既不调用resolve也不调用reject,promise则一直处于等待状态,也就不会走到then方法。
let p = new Promise((resolve, reject) => {console.log(1);
});
p.then(() => {console.log('成功')}, () => {console.log('失败')})//1
如果你既调用resolve也调用reject,那么谁在前面执行就走谁的对应回调函数
let p = new Promise((resolve, reject) => {console.log(1);resolve()//先调用成功reject()
});
p.then(() => {console.log('成功')}, () => {console.log('失败')})//1 成功
let p = new Promise((resolve, reject) => {console.log(1);reject()//先调用失败resolve()
});
p.then(() => {console.log('成功')}, () => {console.log('失败')})//1 失败
如果代码出错则会直接走reject的回调
let p = new Promise((resolve, reject) => {console.log(1);throw new Error('出错了~')
});
p.then(() => {console.log('成功')}, () => {console.log('失败')})//1 失败
一个promise的实例可以then多次
let p = new Promise((resolve, reject) => {resolve('成功了');
});
p.then((data) => {console.log(data)//成功了
});
p.then((data) => {console.log(data)//成功了
})
利用promise解决回调地狱
能够规避异步操作中回调地狱的问题,其本质取决于promise的链式调用。
假设需求如下,a.txt文件的内容为b.txt,b.txt文件的内容是一段描述文字,现在要求用a.txt的得到最终的描述文字,代码如下:
let fs = require('fs');
//首先将异步方法封装在一个promise中,异步结果成功调用resolve方法,失败调用reject方法。
function read(url) {return new Promise((resolve, reject) => {fs.readFile(url, 'utf8', function (err, data) {if (err) reject();resolve(data);})})
}
//因为read方法返回的是一个promise,所以可以使用promise的then方法
read('a.txt').then((data) => {
//第一次异步成功后拿到结果继续返回一个promise可以实现链式调用。console.log(data);//b.txt
return read(data);
}, (err) => { }).then((data) => {
//最后两次的结果分别对应两次异步的返回内容console.log(data)//描述文字
}, (err) => { })
总结:如果一个promise的then方法中还返回另一个promise,那么这个promise的成功状态会走到外层promise的下一次then方法的成功,如果失败,返回外层promise下一次then的失败。
promise的链式调用
- 如果then中返回的是一个普通值,就会走到下一次then的成功回调。
read().then((data) => {
return 111
}, (err) => { }).then((data) => {
console.log(data)//111
}, (err) => { })
- 如果then中返回的是一个错误,就会走到下一次then的失败回调。
read().then((data) => {
throw new Error('出错了~')
}, (err) => { }).then((data) => {
console.log(data)
}, (err) => {
console.log(err)//出错了~
})
- 如果then中什么也不返回,就会走到下一次then的成功回调,得到的值为undefined。
read().then((data) => {
cons.log(111)
}, (err) => { }).then((data) => {
console.log(data)//undefined
}, (err) => {
})
- 如果想统一处理错误内容,可以使用catch。
read().then((data) => {
throw new Error('出错了~')
}, (err) => { }).then((data) => {}, (err) => {}).catch((err)=>{//错误处理
})
- 统一处理错误后,还可以使用then。
read().then((data) => {
throw new Error('出错了~')
}, (err) => { }).then((data) => {}, (err) => {}).catch((err)=>{//错误处理
}).then((data) => {}, (err) => {})
Promise.all()
all方法可以处理多个请求并发的问题。参数是一个数组。all方法调用后会返回一个新的promise。
let fs = require('fs');
function read(url) {return new Promise((resolve, reject) => {fs.readFile(url, 'utf8', function (err, data) {if (err) reject();resolve(data);})})
}
Promise.all([read('1.txt'), read('2.txt')]).then((data) => {console.log(data)//[ '文本1内容', '文本2内容' ]
}, (err) => {console.log(err);
})
在all方法中一个失败了就全部失败,所以都成功了才会走成功回调。
Promise.all([read('1.txt'), read('3.txt')]).then((data) => {console.log(data)
}, (err) => {console.log('失败了');//失败了
})
Promise.race()
多个请求中,谁的返回数据最快,结果就是谁
Promise.race([read('1.txt'), read('2.txt')]).then((data) => {console.log(data)文本2内容
}, (err) => {console.log('失败了');//失败了
})
Promise.resolve()
返回一个成功的Promise
Promise.resolve('123').then((data) => {console.log(data)//123
})
Promise.reject()
返回一个失败的Promise
Promise.resolve('123').then((data) => {console.log('err', data)//err 123
})
如果你想手写一个promise,请戳下面的链接:
手写promise
转载于:https://www.cnblogs.com/hanqingtao/p/9963957.html
es6中的promise解读相关推荐
- 【JavaScript 教程】ES6 中的 Promise对象 详解
[JavaScript 教程]ES6 中的 Promise对象 详解 1.Promise对象含义 promise是异步编程的一种解决方法. 所谓promise,简单说是一个容器,里面保存着某个未来才会 ...
- ES6中的Promise
ES6中的Promise JavaScript本身是单线程语言,这在Node.js学习中已经反复强调过,因为单线程,就需要在程序进行IO操作时做"异步执行",比如最典型的网络操作- ...
- ES6中的Promise使用方法与总结
在javascript中,代码是单线程执行的,对于一些比较耗时的IO操作,都是通过异步回调函数来实现的. 但是这样会存在一个问题,当下一个的操作需要上一个操作的结果时,我们只能把代码嵌到上一个操作的回 ...
- Promise使用详解2(ES6中的Promise)
2015年6月, ES2015 (即 ECMAScript 6 . ES6 ) 正式发布.其中 Promise 被列为正式规范,成为 ES6 中最重要的特性之一. 1,then()方法 简 ...
- ES6中的Promise详解
Promise 在 JavaScript 中很早就有各种的开源实现,ES6 将其纳入了官方标准,提供了原生 api 支持,使用更加便捷. 定义 Promise 是一个对象,它用来标识 JavaScri ...
- promise ajax 队列,ES6中的promise,从使用promise封装ajax说起
1为啥要用promise? js是单线程的,理论上所有代码都是同步的,从上到下一行行执行.然而就这样傻傻解析运行js的话,碰到较重的任务时,会阻塞进程,如发送一个用户是否登录验证请求,请求完成响应之前 ...
- ES6中的promise、async、await用法详解
<!DOCTYPE html> <html> <head><title>Promise.async.await</title> </h ...
- 大白话讲解Promise(三)搞懂jquery中的Promise
前两篇我们讲了ES6中的Promise以及Promise/A+规范,在Promise的知识体系中,jquery当然是必不可少的一环,所以本篇就来讲讲jquery中的Promise,也就是我们所知道的D ...
- 浅析JaveScript中的Promise对象 暮雨清秋
前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法.并在文末会附上一份符合PromiseA+规范的Promise对象的完整实现. 注:本文中的相关概念均基 ...
最新文章
- 函数指针(就做个笔记)
- 事件相机角点检测,从原理到demo
- 【其他】GIT常用原生命令
- Java多线程闲聊(三):RxJava
- 在 Mac 上多开微信,还能看到朋友撤回的信息:WeChatTweak
- android 设置对话框的高度,如何控制Android中默认警报对话框的宽度和高度?
- 深入理解分布式系统的2PC和3PC
- javascript window.navigator
- 吃透web前端秘籍,来听听大佬是怎么说的
- 王道机试指南读后总结-1
- 为什么下拉框拉不下来_为什么分手后对方不删除拉黑你,但又不和你复合?
- [2018.09.05 T1] Lyk Love painting
- vs2010操作office2010
- office文档转html,OFFICE 文档转换为html在线预览
- 模拟太阳系的html,three.js模拟实现太阳系行星体系功能
- ar 华为路由器 端口映射_华为AR1220-S路由器WEB界面鸡肋使用命令映射多端口方法...
- ofd电子文档内容分析工具(分析文档、签章和证书)
- linux分区方案探讨
- 文件上传漏洞之——远程文件包含漏洞(RFI)
- 没有什么比穷可怕_真正可怕的是没有人再在乎
热门文章
- linux 打包库文件,Linux的文件的打包(tar方法)
- 中文论文万能句型_干货|SCI论文写作的万能句型~
- 防统方系统服务器的拼音,横渡医院防统方系统软件技术参数(最新)
- 怎么把文件上传云服务器上,如何把文件上传到云服务器上
- mysql 比较一个字符串_比较MySQL中的两个字符串?
- python `__hash__`
- java 对象和类
- 虚拟机打不开,提示“此主机不支持虚拟化实际模式”的解决方法。
- 在 里面_适合县城里面加盟的鞋店推荐
- Mysql学习总结(73)——MySQL 查询A表存在B表不存在的数据SQL总结