什么是Promise?
Promise是异步编程的一种解决方案。
什么时候会来处理异步事件,一种较常见场景就是网络请求。
当进行封装一个网络请求的函数时,因为不能立即拿到结果所以不能像3+4=7一样将结果返回,所以往往我们会传入另一个函数,在数据请求成功时将数据通过传入的函数回调出去,如果只是一个简单的网络请求,这种方案不会给我们带来很大的麻烦。
但是当网络请求非常复杂时,就会出现回调地狱。
例如这个场景
我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2;
我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url2;
我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4;
发送网络请求url4,获取最终的数据data4
使用ajax实现:
$ajax('url1',function (data1) {
$ajax(data1['url2'], function(data2) {
$ajax(data2['url3'], function(data3) {
$ajax(data3['url4'], function(data4) {
console.log(data4);
})
})
})
})
上面的解决方法比较难看且不易维护,若两个请求之间隔了很长其他的代码会更乱,而Promise可以以一种非常优雅的方式来解决这个问题。😊😊😊
//resolve,reject本身也是函数,同时也是参数
//当执行resolve时去执行then
new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
},1000)
}).then(() => {
})
什么情况下用promise?
一般情况下是有异步操作时,使用Promise对这个异步操作进行封装。
new Promise((resolve, reject) => {
setTimeout(() => {
/* resolve('hello world') */
reject('error message')
}, 1000)
}).then(data => {
console.log(data);
}).catch(err => {
console.log(err);
})
Promise的三种状态
首先当我们开发中有异步操作时,就可以给异步操作包装一个Promise,异步操作之后有三种状态。
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间;
fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then();
reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch();
Promise的链式调用
在看Promise的流程图时,无论是then还是catch都可以返回一个Promise对象,所以代码可以进行链式调用。
直接通过Promise包装新数据,将Promise对象返回:
Promise.resovle():将数据包装成Promise对象,并且在内部回调resolve()函数;
Promise.reject():将数据包装成Promise对象,并且在内部回调reject()函数。
链式调用简写
如果希望数据直接包装成Promise.resolve,那么在then中可以直接返回数据。
new Promise((resolve, reject) => {
setTimeout(function () {
resolve('Hello world')
}, 1000)
}).then(data => {
console.log(data); //Hello world
return data + '111'
}).then(data => {
console.log(data); //Hello world111
return data + '222'
}).then(data => {
console.log(data); //Hello world111222
return Promise.reject(data + 'error')
}).then(data => {
console.log(data); //这部分不会输出,这部分代码不会执行
return data + '333'
}).catch(data => {
console.log(data); // Hello world111222error
return data + '444'
}).then(data => {
console.log(data);//Hello world111222error444
})
Promise的all方法使用
当同时有两个请求且两个请求都获取后才能进行后续功能。
//使用ajax方法解决
//请求一:
//写两个变量用来判断哪个请求先请求到
let isResult1 = false
let isResult2 = false
$ajax({
url: '',
success: function() {
console.log('结果一')
isResult1 = true
handleResult()
}
})
//请求二:
$ajax({
url: '',
success: function() {
console.log('结果二')
isResult2 = true
handleResult()
}
})
function handleResult() {
//判断当两个变量都为true时进行后续功能开发
if (isResult1 && isResult2) {
}
}
使用Promise .all,用于某一个需求需要两次请求
Promise.all([
new Promise((resolve, reject) => {
$ajax({
url: 'url1',
success: functionn(data) {
resolve(data)
}
})
}),
new Promise((resolve, reject) => {
$ajax({
url: 'url2',
success: functionn(data) {
resolve(data)
}
})
}).then(result => {
results[0]
results[1]
})
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({name: 'why', age: 18})
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({name: 'why', age: 19})
}, 1000)
})
]).then(results => {
console.log(results)
})
(如有错误请指正)