JavaScript的ES6新增了Promise异步请求功能,使得前端请求后端数据的功能更加容易。由于JS是单线程语言,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。为了让JS实现多线程的任务,掌握Promise的使用是每个前端开发者必备技能之一。
一、什么是Promise
Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大。从语法上说,Promise是一个构造函数;从功能上来说通过创建一个Promise对象,用于封装异步操作并取得结果。Promise提供统一的API,处理异步操作。Promise最大的作用是解决了“回调地狱”的问题:即当一次操作需要多次网络请求时,传统的异步代码会产生大量的代码嵌套,降低了代码可读性和复用性;而Promise的写法更加直观,且Promise能够在外部捕获异常,这是传统的异步请求都无法做到的。
简单的Promise例子
let p = new Promise(function(resolve,reject){//通过new方法创建Promise
resolve(1);//调用成功的回调函数
})
p.then(function(res){
console.log(res);
return 2;
}).then(function(res2){
console.log(res2)
})
Promise方法的框架简写
function f1(){
.....
return new Promise ((resolve,reject)=>{
//执行方法
//eg.
console.log('测试')
.then(response=>{
resolve(response)
//数据的其他处理等操作
})
.catch(error=>{
reject(error);
})
})
}
二、Promise对象的两个特点
2.1对象的状态不受外界影响
Promise对象有三种状态:
pending(进行中)
fulfilled(已成功)
rejected(已失败)
2.2一旦状态改变,就不会在变,任何时候都可以得到这个结果
状态转换:pending——》fufilled或resolved——》表示成功
状态转换:pending——》rejected——》表示失败
Promise的状态的转换只有这两种,且Promise对象只能改变一次,无论成功还是失败都只会返回一个结果数据;成功的的为value,失败的数据称为reason。
三、then方法
Promise的实例是一个异步操作,函数内部拿到操作结果后,无法使用return把操作结果返回给调用者 ,这个时候只能使用 回调函数的形式,把成功或失败的结果,返回给调用者。具体通过then方法resolve函数和reject函数实现。
Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。
3.1 resolve回调函数
Promise异步执行成功,调用resolve把结果返回给调用者(如返回一个值),见下面的例子
3.2 reject回调函数
Promise异步执行失败,调用reject把结果返回调用者(如抛出异常),见下面的例子
四、catch方法
与Promise对象方法then方法并行的一个方法就是catch,与try catch类似,catch就是用来捕获异常的,也就是和then方法中接受的第二参数rejected的回调是一样的。但是,它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。
如下的例子中,在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数。调用某个执行方法后,接口返回的数据存储与response中,之后可以对数据进行相应的处理等。错误的异常通过catch捕捉。
mounted(){
this.promiseTest();
},
methods:{
promiseTest(){
return new Promise(function(resolve, reject){
setTimeout(function(){
var str = "创建一个Promise对象吧"
if((typeof str) =='string'){
console.log('resolve成功,值为:'+str)
resolve(str);
}
else{
console.log('reject拒绝')
reject('非字符串');
}
}, 2000);
})
.then(function(value){
console.log('resolved成功回调');
console.log('成功回调接受的值:',value);
console.log(noData);
})
.catch(function(reason){
console.log('catch到rejected失败回调');
console.log('catch失败执行回调抛出失败原因:',reason);
})
}
}
打开控制台,输出如下内容
then方法中执行成功的返回成功的函数和值,执行失败的返回失败的原因,reject捕捉不到的异常,catch方法捕捉并输出错误信息。
五、缺点
1.无法取消Promise,Promise一旦新建立即执行,无法中途取消。
2.如果不设置回调函数,Promise内部抛出的错误不会反映到外部。
3.当处于pending状态时,无法得知目前在哪一阶段