此篇文章主要参考大白话讲解Promise
new Promise(function(resolve, reject) {
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
在上面的代码中,首先执行了一个异步操作,也就是setTimeout,在2秒后输出“执行完成”,并且调用resolve方法。需要注意的是,在上面代码中,只是new了一个promise对象,并没有去调用而它就执行了,所以在使用promise的时候一般把它封装在一个函数里,然后去运行这个函数,代码如下:
function runAsync() {
return new Promise(function(resolve, reject) {
// 做一些异步操作
setTimeout(function() {
console.log('执行完成');
resolve('随便什么数据');
}, 2000)
})
}
reunAsync();
接上面代码,直接使用
renAsync().then(function(data) {
console.log(data);
});
then接受一个参数,是函数,此函数也接收一个参数,是runAsync函数中resolve传的参。运行这段代码,会输出
执行完成
随便什么数据
then方法还有更骚气的用法,就是无限链式调用
function runAsync1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 2000);
});
}
function runAsync2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
}
function runAsync3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
}
runAsync1().then(data => {
console.log(data);
return runAsync2();
}).then(data => {
console.log(data);
return runAsync3();
}).then(data => {
console.log(data);
})
输出
异步任务1执行完成
随便什么数据1
异步任务2执行完成
随便什么数据2
异步任务3执行完成
随便什么数据3
需要注意的是,then方法在链式调用时,then方法可以return一个promise对象,也可以return一个数据
runAsync1().then(data => {
console.log(data);
// return runAsync2();
return '123';
}).then(data => {
console.log(data);
return runAsync3();
}).then(data => {
console.log(data);
});
这样返回的数据就变成了
异步任务1执行完成
随便什么数据1
123
异步任务3执行完成
随便什么数据
如果不显式return数据的话,因为函数默认return undefined,所以下一个then方法接收到的参数就是undefined。 即上面结果中123的位置就是undefined,但是注意,then方法的链式调用依然会进行下去,不会被阻止
如果return的是promise对象的话,那这个promise对象必须resolve一个数据,否则,会终止链式调用,比如将上面的runAsync1函数做如下修改
function runAsync1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步任务1执行完成');
return '123';
// resolve('随便什么数据1');
}, 2000);
});
}
则返回数据只有一句
异步任务1执行完成
在上面的例子中,我们都是执行回调成功用resolve抛出数据,如果执行回调失败的话,我们就用reject抛出数据;
function getNumber() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const num = Math.ceil(Math.random() * 10);
if (num <= 5) {
resolve(num);
} else {
reject('数字太大了');;
}
}, 2000)
})
}
getNumber().then(
data => {
console.log('resolved:', data);
},
data => {
console.log('reject:', data);
}
)
输出为
resolved: 4
或
reject: 数字太大了
catch用法和then的第二个参数一样,是指定reject的回调的,用法如下:
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
其效果和写在then的第二个参数里面一样。不过它还有另一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,抛出异常的话,那么代码并不会报错卡死,而是会进入到这个catch方法中。
all方法接收一个数组作为参数,数组里面的值最终都返回后,才会进入then里面。代码如下
Promise.all([runAsync1(), runAsync2(), runAsync3()])
.then(res => {
console.log(res);
});
返回值是:
异步任务1执行完成
异步任务2执行完成
异步任务3执行完成
(3) [“随便什么数据1”, “随便什么数据2”, “随便什么数据3”]
需要注意的是如果数组里的某个值得返回值是promise对象时,必须resolve数据,否则永远不会进入then方法中。
因为用到的比较少,所以不做介绍,如果有需要,请自行查询大白话讲解Promise。