用Promise解决多个异步Ajax请求导致的代码嵌套问题
function a(){
return new Promise(function(resolve, reject){
resolve("a()");
})
}
function b(data){
return new Promise(function(resolve, reject){
resolve("b()" + data);
})
}
function c(data){
return new Promise(function(resolve, reject){
resolve("c()" + data);
})
}
处理程序
a().then(function(data){
return b(data);
}).then(function(data){
return c(data);
}).then(function(data){console.log(data)});
Promise的基本用法
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'done');
})
p1.then(data => {
console.log(data);
})
Promise一个明显的好处便是可以用来解决回调地狱。特别是在处理多个回调依赖的情况。 使用Promise解决多个异步依赖调用
Promise提供了一个方法Promise.all([p1, p2, p3])
,用于将多个Promise实例,包装成一个新的Promise实例。接收的参数是一个数组,p1、p2、p3都是Promise对象。接收的参数是一个数组,p1、p2、p3都是Promise对象。
此时Promise.all的状态取决于它的参数
分两种情况
- p1、p2、p3的状态都是resolve的时候, Promise.all的状态才会变成resolve;
- 只要p1、p2、p3中有一个的状态为reject,那么Promise.all的状态就会变成reject;
所以我们可以用Promise.all()来解决多个异步调用。
比如我们平常经常遇到的一种情况:
网站中需要先获取用户名,然后再根据用户名去获取用户信息。这里获取用户名getUserName()
和获取用户信息getUser()
都是调用接口的异步请求。在获取用户信息之前,需要先获取用户名。也就是说getUser依赖于getUserName的状态。所以我们可以将这两个请求通过Promise.all()封装成一个新的Promise对象。
function getUserName(){
let data = 'superman';
return new Promise((resolve, reject) => {
setTimeout(resolve(data), 1000);
}
}
function getUser(){
let data = {
id: 1,
username: 'superman',
gender: 'male'
}
return new Promise((resolve, reject) => {
setTimeout(resolve(data), 2000);
})
}
getUserPromise(getUserName(), getUser())
.then(data => {
console.log(data);
})
使用Promise的链式调用
function getUserName(){
let data = 'superman';
return new Promise((resole, reject) => {
setTimeout(resolve(data), 4000);
})
}
function getUser(username){
let data = {
id: 1,
username: 'superman',
gender: 'male'
}
return new Promise((resolve, reject) => {
if(username){
setTimeout(resolve(data), 2000);
}else{
reject('err');
}
})
}
getUserName().then(username=>{
return getUser();
}).then(user => {
console.log(user);
}).catch(err => {
console.log(err);
});