回调地狱的产生
无法保证顺序的代码:
fetch('/demo1', function (err, data1) {
console.log(data1)
})
fetch('/demo2', function (err, data2) {
console.log(data2)
})
fetch('/demo3', function (err, data3) {
console.log(data3)
})
由于是fetch是异步的,无法保证请求是按照顺序来请求的
如何保证顺序呢?通过回调的方式保证其顺序
fetch('/demo1', function (err, data1) {
console.log(data1)
fetch('/demo2', function (err, data2) {
console.log(data2)
fetch('/demo3', function (err, data3) {
console.log(data3)
})
})
})
这里只有三个异步函数,如果多个,会产生回调地狱。
一个任务依赖于一个异步任务执行完之后,这里必须进行嵌套才能解决。
问题:嵌套的太深,代码不好看,很难维护
怎么去解决这个问题呢?在ES6中新增了一个API——Promise
Promise是如何解决回调地狱的
promise是一个容器
,里面存放了一个正在执行的任务(pending:正在执行),这个任务执行结束后,可能有两个状态,resolved(完成)和 rejected(失败),状态只能是其中的一种
promoise的使用
promise是一个构造函数
//重点:promise容器一旦创建,就开始执行里面的代码,容器里可以放置异步函数
var p1 = new Promise(function(resolve,reject){
console.log('hello') //这里的代码不是异步的
fetch('/demo1',function(err,data){
if(err){
// 承渃容器中的任务失败了,把容器的Pending状态变为 Rejected
reject(err)
}else{
//承渃容器中的任务成功了,把容器的Pending状态变为 Resolved
resolve(data)
}
})
})
//p1就是那个承诺
p1.then(function(data){ // resolved状态下调用
console.log(data)
}).catch(function(err){ // rejected状态下调用
console.log(err)
})
promise解决回调地狱问题示例
var p1 = new Promise(function(resolve,reject){
fetch('/demo1', function(err,data){
if(err){
reject(err)
}else{
resolve(data)
}
})
})
var p2 = new Promise(function(resolve,reject){
fetch('/demo2', function(err,data){
if(err){
reject(err)
}else{
resolve(data)
}
})
})
var p3 = new Promise(function(resolve,reject){
fetch('/demo3',function(err,data){
if(err){
reject(err)
}else{
resolve(data)
}
})
})
p1
.then(function (data) {
console.log(data)
//当你return 123 后面接接收到 123
// return 'hello' 后面就接收到 ’hello'
// 没有return后面收到的就是undefined
//上面那些return的数据没什么卵用
//真正有用的是:我们可以return一个promise对象
//当return一个Promise对象的时候,后续的then中的方法的第一个参数会作为p2的resolve
return p2
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
})
.catch(err => { // 下面会介绍
console.log(err)
})
再谈Promise
Promise.resolve
Promise.resolve(x)等价于
x instanceof Promise ? x : new Promise(resolve=>resolve(x))
Promise.reject
Promise.reject等价于
new Promise((resolve,reject)=>reject(x))
then
我们目前为止看到的then都是接受一个handler,其实它可以接收两个参数,一个用于fulfillment,一个用于rejection。而且Promise.catch等价于Promise.then(undefined,rejectionHadler)。
p1.then(result=>{
},error=>{
})
这个跟
p1.then(result=>{
}).catch(error=>{
})
可不等价,前者两个handler都注册在同一个Promise上,而后者catch注册在then返回的Promnise上,这意味着如果前者里只有p1出错了才会被处理,而后者p1出错,以及then返回的Promise出错都能被处理
catch
catch的作用我们刚刚也讨论过了,它会注册一个函数在Promise进入rejected状态时调用,除了这个,其他行为可以说跟then一模一样
p1.catch(error=> conseole.log(error)
finally
不论是 resolved 还是 rejected 状态,最终都会被执行
p1.then(resolved => { console.log('hello') }).catch(error=> conseole.log(error)).finally{ console.log("最终都会被执行") }
Promise中的工具函数
持续更新…