ES6处理异步的方式promise
1、promise初使用
大多数情况我们发起网络请求的时候都是利用Ajax异步请求。所以这个时候Ajax在没有得到请求的结果时是线程是异步的。在ES6的新语法中就有了promise这样一个类来更加优美地处理异步和异步的嵌套。
假如我们想要发起一个请求一,然后利用请求一得到的结果再发起请求二,再利用请求二的结果发起请求三,嵌套下去,我们的代码就会像这样:
$.ajax({// 请求1
success(res) {
$.ajax({// 请求2
success(res) {
$.ajax({// 请求3
success(res) {
},
});
},
});
},
});
无限套娃,就会看起来特别累,所以promise就能更加优雅地处理异步。
首先我们先需要new一个promise对象:
new Promise();
他的构造函数需要一个参数,这个参数是一个函数:
new Promise(function () {
});
然后这个函数需要两个参数,分别是resolve(解决)和reject(拒绝):
new Promise(function (resolve, reject) {
});
这样我们就可以在这个函数里面写异步体了,比如发送一个请求:
new Promise(function (resolve, reject) {
//异步体
$.ajax({
//请求的地址
url: '',
//请求类型
type: '',
//异步开启
async :true,
//请求的参数
data: {},
//请求成功的回调函数
success(res) {
console.log(res);
},
//请求失败的回调函数
error(res) {
console.log(res);
}
});// ajax
});
然后promise厉害的一点就是不会在异步体里处理请求成功的数据,而是在外面,相当于异步体和异步结果的处理分开了:
new Promise(function (resolve, reject) {
//异步体
$.ajax({
//请求的地址
url: '',
//请求类型
type: '',
//异步开启
async :true,
//请求的参数
data: {},
//请求成功的回调函数
success(res) {
console.log(res);
},
//请求失败的回调函数
error(res) {
console.log(res);
}
});// ajax
}).then(function () {
});
这个then函数的参数函数里就是对异步结果的处理,比如我想要打印上面ajax请求成功的结果:
new Promise(function (resolve, reject) {
//异步体
$.ajax({
//请求的地址
url: '',
//请求类型
type: '',
//异步开启
async :true,
//请求的参数
data: {},
//请求成功的回调函数
success(res) {
resolve(res);// 调用resolve利用then函数来处理
},
//请求失败的回调函数
error(res) {
console.log(res);
}
});// ajax
}).then(function (res) {
// 异步成功结果处理
console.log(res);
});
promise比较厉害的一点就是在then里定义好对异步成功结果的处理,然后在异步体里成功的地方直接调用resolve(),实际上就是调用了then函数。同理,这是异步成功,异步失败的话就定义一个catch函数来捕获失败就好了:
new Promise(function (resolve, reject) {
//异步体
$.ajax({
//请求的地址
url: '',
//请求类型
type: '',
//异步开启
async :true,
//请求的参数
data: {},
//请求成功的回调函数
success(res) {
resolve(res);// 调用resolve利用then函数来处理
},
//请求失败的回调函数
error(res) {
reject(res);// 调用reject利用catch函数来处理
}
});// ajax
}).then(function (res) {
// 异步成功结果处理
console.log(res);
}).catch(function (res) {
// 异步失败结果处理
console.log(res)
});
在catch函数里定义好异步失败结果的处理,然后在异步体里的失败处调用reject函数就可以使用catch里的代码了。
总结,promise实质上就是:
new Promise(/*异步体*/).then(/*异步成功结果的处理*/).catch(/*异步失败结果处理*/);
链式编程,第一个Promise需要传递的参数就是异步体,then里需要传递的就是对异步体成功结果的处理,catch就是对异步失败结果的处理。只不过这三个需要传递的参数就都是函数而已:
new Promise(function (resolve,reject) {
/*异步体*/
}).then(function () {
/*异步成功结果的处理*/
}).catch(function () {
/*异步失败结果处理*/
});
2、利用promise处理异步嵌套
所以刚才上述讲到的ajax异步请求嵌套就可以利用promise来更优美的处理:
先写好第一个promise处理异步:
new Promise(function (resolve,reject) {
$.ajax({ //请求一
success(res) {
console.log(res);
},
});
}).then(function () {
/*异步成功结果的处理*/
});
然后在then里写好对请求一结果的处理并且发起请求二:
new Promise(function (resolve,reject) {
$.ajax({ //请求一
success(res) {
resolve(res);
},
});
}).then(function (res) {
// 拿到res并处理
// 发起请求二
return new Promise(function (resolve,reject) {
$.ajax({ //请求二
success(res) {
console.log(res);
},
});
}).then(function () {
/*异步成功结果的处理*/
});
});
需要在第一层promise的then里返回一个新的Promise对象,然后像之前promise一样处理就好了,定义好异步体,异步成功的处理,异步失败的处理,所以上述三层请求嵌套就是:
new Promise(function (resolve,reject) {
$.ajax({ //请求一
success(res) {
resolve(res);// 利用promise1的then
},
});
}).then(function (res) {
// 拿到请求一的res并处理
// 发起请求二
return new Promise(function (resolve,reject) {
$.ajax({ //请求二
success(res) {
resolve(res);// 利用promise2的then
},
});
}).then(function () {
// 拿到请求二的res并处理
// 发起请求三
return new Promise(function (resolve,reject) {
$.ajax({ //请求三
success(res) {
resolve(res);// 利用promise3的then
},
});
}).then(function () {
/*异步3成功结果的处理*/
});
});
});
3、利用promise.all处理异步
有的时候我们需要利用两个请求的共同结果来进行处理,比如现在有ajax1和ajax2,接下来我需要的是必须将两个请求的结果拿到,然后再将结果进行处理,少了一个就不行,这个时候我们就可以利用promise的all来处理这种异步。
首先,我们需要利用Promise对象的all()方法,这个all方法需要的参数是一个Promise对象数组:
Promise.all([]);
我们给他传入两个promise对象:
Promise.all([
//promise1
new Promise(function (resolve,reject) {
/*异步体*/
}),
//promise2
new Promise(function (resolve,reject) {
/*异步体*/
}),
]);
然后对两个的结果进行共同处理:
Promise.all([
//promise1
new Promise(function (resolve,reject) {
/*promise1异步体*/
}),
//promise2
new Promise(function (resolve,reject) {
/*promise1异步体*/
})
]).then(function (results) {
/*对promise数组的结果进行共同处理*/
});
共同处理的then函数里的results就是promise异步成功结果的数组,比如promise1异步成功的结果就是results[0],promise2异步成功的结果就是results[1]:
Promise.all([
//promise1
new Promise(function (resolve,reject) {
/*promise1异步体*/
}),
//promise2
new Promise(function (resolve,reject) {
/*promise1异步体*/
})
]).then(function (results) {
/*对promise数组的结果进行共同处理*/
console.log(results[0]);// promise1的成功结果
console.log(results[1]);// promise2的成功结果
});
比如我利用两个ajax请求模拟:
Promise.all([
//promise1
new Promise(function (resolve,reject) {
$.ajax({// 请求1
success(res) {
resolve(res); //将请求1的结果传递给then
}
});
}),
//promise2
new Promise(function (resolve,reject) {
$.ajax({// 请求2
success(res) {
resolve(res); //将请求2的结果传递给then
}
});
})
]).then(function (results) {
/*对promise数组的结果进行共同处理*/
console.log(results[0]);// promise1的成功结果
console.log(results[1]);// promise2的成功结果
});
总结就是利用Promise.all()同时处理多个异步,然后传递promise对象进行各自的异步处理,最后在利用Promise.all()的then来将获得的results成功结果数组进行统一处理。