一、 为什么是 Promise?
1 所有的 js 代码都是单线程执行的。
所有的事件,渲染,一切都是单线程的,我们并不希望个耗时操作阻塞用户进程,于是就有了异步
的概念。
1.1 异步的基本原理
JavaScript 引擎负责解析,执行 JavaScript 代码,但它并不能单独运行,通常都得有一个宿主环境,一般如浏览器或 Node 服务器,前文说到的单线程是指在这些宿主环境创建单一线程,提供一种机制,调用 JavaScript 引擎完成多个 JavaScript 代码块的调度,这种机制就称为事件循环( Event Loop )。
1.2 异步的常见实现方法
- 回调函数
- Promise对象
- Generator
1.3 为什么选择 Promise
1.3.1 回调函数
回调函数在处理越多的异步逻辑时,就需要越深的回调嵌套(回调地狱):
1.代码逻辑书写顺序与执行顺序不一致,不利于阅读与维护。
2.异步操作的顺序变更时,需要大规模的代码重构。
3.回调函数基本都是匿名函数,bug 追踪困难。
1.3.2 Generator
Generator 虽然也可以实现异步,但他仍是一个新的标准。 推荐大家去尝试一下这种新的写法。 不仅仅是在 dva 中使用。
Promise 可以更直观
,更易用
的方式 来解决 "回调地狱"
二、什么是 Promise?
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
有个标准叫做: Promises / A +
ES6 规定,Promise
对象是一个构造函数,用来生成Promise
实例。
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。
Promise 新建后就会立即执行。
new Promise((resolve, reject) => {
resolve(1)
})
new Promise((resolve, reject) => {
reject(1)
})
1 术语
"promise"是具有then方法的对象或函数,其行为符合此规范。
"thenable"是定义then方法的对象或函数。 thenable对象指的是具有then方法的对象。
"value"是任意合法的Javascript值,(包括undefined,thenable, promise)
"exception"是使用throw语句抛出的值
"reason"是表示promise为什么被rejected的值
2 Promise 相当于一个状态机
一个 promise 必须处于三种状态之一: 请求态(pending), 完成态(fulfilled),拒绝态(rejected)
- 当promise处于请求状态(pending)时,promise可以转为fulfilled或rejected状态
- 当promise处于完成状态(fulfilled)时
- promise不能转为任何其他状态
- 必须有一个值,且此值不能改变
- 当promise处于请求状态(pending)时
- promise不能转为任何其他状态
- 必须有一个原因(reason),且此原因不能改变
3.1 then()
Promise.prototype.then()
then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。
// 基本使用
new Promise((resolve, reject) => {
resolve(1)
})
.then(value => {
console.log(value) // 1
})
一般来说,不要在then()
方法里面定义 Reject 状态的回调函数(即then
的第二个参数),总是使用catch
方法。
// then 捕获错误(不建议)
// bad
new Promise((resolve, reject) => {
resolve(1)
})
.then(success => {
console.log(success) // 1
}, error => {
console.log(error)
})
// bad
new Promise((resolve, reject) => {
reject(1)
})
.then(success => {
console.log(success)
}, error => {
console.log('then 捕获错误', error) // then 捕获错误 1
})
.catch(error => {
console.log('catch 捕获错误', error) // 思考:这行会被执行吗??
})
3.2 catch()
// 基本使用
new Promise((resolve, reject) => {
reject(1)
})
.catch(e => {
console.log('e',e) // e 1
})
关于错误捕获:
// try...catch() ?
try{
y + 1
}catch(e){
console.log('try...catch捕获的错误=>',e) // try...catch捕获的错误=> ReferenceError: "y is not defined"
}
// try ...promise... catch() ?
// 1.
try{
new Promise((resolve, reject) => {
reject(1)
c + 1
})
}catch(e){
console.log('try ...promise... catch捕获的错误=>',e) // 思考:c+1 能否被捕获??
}
// 2.
try{
new Promise((resolve, reject) => {
reject(1)
c + 1
})
.catch(e => {
console.log('promise catch捕获的错误',e) // 思考:c+1 能否被捕获??
cc + 1
})
}catch(e){
console.log('try ...promise... catch捕获的错误=>',e) // cc+1 思考:能否被捕获??
}
// 3.
try{
new Promise((resolve, reject) => {
reject(1)
c + 1
})
.catch(e => {
console.log('promise catch捕获的错误',e) // 思考:c+1 能否被捕获??
cc + 1
})
.catch(e => {
console.log('promise catch捕获的错误2',e) // cc+1 思考:能否被捕获??
})
}catch(e){
console.log('try ...promise... catch捕获的错误=>',e) // cc+1 思考:能否被捕获??
}
3.3 all()
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
只有当所有的promise执行完毕并得到结果后才会更改外部promise的状态,并且返回全部的promise的结果。
const promiseList = [0,1,2,3,4,5].map(t => {
return new Promise((resolve,reject) => {
resolve(t+1)
})
})
Promise.all(promiseList).then(res => {
console.log(res) // [1,2,3,4,5,6]
})
3.4 race()
Promise.race()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
只有最早执行完毕的promise会更改外部包装promise的状态,并且只返回最早的promise结果。
// race()
const promise1 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('1000')
},1000)
})
const promise2 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('500')
},500)
})
Promise.race([promise1,promise2]).then(res => {
console.log(res) // '500'
})
3.5 finally()
三、一些思考
1 then()中有then() ?
2 catch() + then() ?
3 如何使用Promise ?
4 all() 的catch() ?
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!