ES6 中一个非常重要和好用的特性就是Promise
promise 到底是做什么的呢?
promise 是异步编程的一种解决方案。
那什么时候我们回来处理异步事件呢?
1.一种很常见的场景就是网络请求
2.我们分装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4 = 7一样将结果返回。
3.所以我们往往会传入另外一个函数,在数据请求成功的时候,将数据同过传入的函数回调出去。
4.如果知识一个简单的网络请求,那么这种方案就不会给我们带来很大的麻烦。
但是当网络请求非常复杂时,就会出现回调地狱。
案例需求:
1.ajax请求一个data1,包含一个url1
2.url中包含下一个请求的url2
3.url2中包含下一个请求的url3
4.url3中包含一个下一个请求的url4
5.url4中返回最终数据data4
$.ajax('url1',function(data){
$.ajax(data1['url2'],function(data2)){
$.ajax(data2['url3'],function(data3)){
$.ajax(data3['url4'],function(data4)){
console.log(data4)
}
}
}
})
这样看来并没有什么问题。
如果我每一次请求都有100行代码处理数据,这样代码看起来就会很乱,而且难以维护!
//1.参数是两个函数 resolve 和 reject 而resolve 和 reject本身又是函数
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('hello promise')
},1000)
})
//2.如果说我要在promise中执行多个异步操作
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第一次请求');
setTimeout(() => {
console.log('第二次请求');
setTimeout(() => {
console.log('第三次请求');
},1000)
},1000);
},1000)
})
//这种在执行完1后执行2再执行3,就出现了我们所说的回调地狱。
//所以我们希望能将里面的多个请求提取出来
首先,往我们开发中有异步操作的时候,就可以给异步操作包装一个Promise
异步操作之后会有三种状态
1.pendding() 等待状态,比如正在进行网络请求,就处于该状态,或者定时器还没有到时间
2.fulfill() 满足状态,当我们主动回调了resolve(),就处于这中状态,并且会回调then()
3.reject() 拒绝状态,当我们主动回调了rehect(),就处于这种状态,并且会回调catch()
promise解析: 当你new完promise的时候就会传回来两个参数,resolve和reject,同时那两个参数也是函数。
new -> (构造函数)
1.保存一些状态信息。
2.执行传入的函数。
3.执行这个回调函数的时候会传入两个参数resolve和reject,同时这两个参数又是函数。
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(); //传入resolve(),可以调用.then() 执行.then()
},1000)
}).then(()=>{
console.log('第一次请求');
return new Promise((resolve, reject)=>{
setTimeout(() => {
resolve();
},1000)
}).then(() => {
console.log('第二次请求');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
},1000)
}).then(()=>{
console.log('第三次请求');
})
})
})
另外一种写法 直接在.then()函数中传入两个函数参数,resolve时执行第一个,reject执行第二个
new Promise((resolve, reject) => {
setTimeout( ()=> {
// resolve('resolve message');
reject('error message');
},1000)
}).then(res =>{
console.log(res)
},data=>{
console.log(data)
})
//系统默认第一个函数为调用resolve时执行的函数,第二个函数为执行reject时执行的函数
需求:请求回来 aaa - > 自己处理
处理 aaa111
处理 aaa111222
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
console.log(res,'第一行的执行结果')
return new Promise((resolve, reject) => {
resolve(res + '111')
})
}).then(res => {
console.log(res,'第二次执行结果');
return new Promise((resolve, reject) => {
resolve(res + '222')
})
}).then(res => {
console.log(res,'第三次处理的结果');
})
promise优雅的处理请求回来的数据
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('xiyounet') //不推荐我们在这里处理请求回来的数据
})
}).then((data)=>{
console.log(data); //xiyouney //通过参数传入到.then()中去处理
console.log(data + 2019); //xiyounet2019
})
这时候我们可以看到promise传入的参数中还有一个reject,那么reject又是来做什么的?
类似于ajax当我们处理请求成功的时候我们需要执行sucess函数,失败执行error,reject就是当我们处理请求失败的时候执行
简单的实例“:
new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(); //这里调用resolve() 就会执行.then()
reject('error message'); //这里调用reject() 就会执行.catch()
})
}).catch((data)=>{
console.log("我是执行的reject函数:"+data)
})
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
console.log(res,'第一行的执行结果')
return Promise.resolve(res + '111')
}).then(res => {
console.log(res,'第二次执行结果');
return Promise.resolve(res + '222');
}).then(res => {
console.log(res,'第三次处理的结果');
})
// 处理结果显示也是 o的 解释; 内部给我们提供了 promise.resolve() 的方法
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
console.log(res,'第一行的执行结果')
return (res + '111')
}).then(res => {
console.log(res,'第二次执行结果');
return (res + '222');
}).then(res => {
console.log(res,'第三次处理的结果');
})
//处理结果也是o的 解释:内部给我们包装了promise
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
console.log(res,'第一行的执行结果')
return Promise.reject('error message');
}).then(res => {
console.log(res,'第二次执行结果');
return Promise.resolve(res + '222');
}).then(res => {
console.log(res,'第三次处理的结果');
}).catch(err => {
console.log(err)
})
//当执行了Promise.reject时,就会直接调用catch(),
//打印结果为: aaa第一行的执行结果 和 error message
//我们也可以通过throw的方法手动抛出错误
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
console.log(res,'第一行的执行结果')
// return Promise.reject('error message');
throw 'error message'
}).then(res => {
console.log(res,'第二次执行结果');
return Promise.resolve(res + '222');
}).then(res => {
console.log(res,'第三次处理的结果');
}).catch(err => {
console.log(err)
})
//这样也是ok的 简直太帅了不要
promise.add() 方法的使用 当一个页面需要所有的网络请求都完成时显示,只有两个结果都请求完成才算成功,这个时候我们使用ajax很难判断哪个请求先完成,以及是否处理代码。
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({name:'kjh',age:20})
},1000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({hobby:'pingpang',wifi:'xiyounet'})
},2000)
})
]).then(result => {
console.log(result[0], result[1]);
})
//3s中后完成两个请求,一起返回数据