Promise 的基本用法
Promise是异步编程的一种解决方案,
Promise的优缺点
优点
将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
缺点
1.无法取消,一旦新建就会立即执行,无法中途取消。
先来看看promise的特性
立即执行
var a = new Promise(fuction(resolve,reject){
console.log(1);立即执行
resolve(2);
});
console.log(3);
a.then((res)=>{
console.log(res);
})
// 1 3 2
不可逆性
var a = new Promise(fuction(resolve,reject){
resolve(1);
});
a.then((res)=>{
console.log(res); //1
return res+1;
}).then((res)=>{
console.log(res); //2
}).then((res)=>{
console.log(res); //undefinde 上面的then的回调一定return出去,下面then的回调才能拿到res,不然underfined,更不会回头找第一个then回调return返回值
});
回调异步
var a = new Promise(fuction(resolve,reject){
resolve(1);
});
console.log(2);
a.then((res)=>{
console.log(res);
})
// 2 1
2.如果不设置回调函数,在Promise内抛出的错误不会反映到外部,无法得知目前的进度。
写法
Promise对象有三种状态
1.Pending,Promise对象的初始状态
2.Resolved,任务执行完成且成功的状态
3.Rejected,任务执行完成且失败的状态
ES6 规定,Promise
对象是一个构造函数,用来生成Promise
实例。
下面代码创造了一个Promise
实例。
const Promise = new Promise(function(resolve,reject){
if(###成功###){
resolve(value);
}else{
reject(error);
}
})
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,#作为参数传递出去#;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,#作为参数传递出去#。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
是Promise构造函数后面就可以then下去,promise这个实例化对象就是一个Promise构造函数
promise.then(function(value) {
success//resolve状态的回调
}, function(error) {
failure//reject状态的回调
});
注意:是Promise构造函数后面就可以then下去,
下面来个封装ajax的例子;
微信ajax例子:
//封装ajax请求
function $request(_url, type, callback, data) {
wx.request({
url: _url, //请求地址
method: type, //请求类型
data, //向后台请求的参数
success(res) { //成功后做的事
callback(res)
}
})
}
//es6
//用promise封装ajax
function promiseAjax(_url, type, data) { //这里不要callback也行
return new Promise(function(resolve, reject) { ////Promise有三种状态(成功,失败,请求的过程),Promise里面接收一个函数 //这个函数有resolve,reject两个参数,分别表示成功回调与失败回调
wx.request({
url: _url,
method: type,
data,
success: (res) => { //成功的回调
resolve(res)
console.log("成功")
},
fail(err) {
reject(err)
console.log("失败") //为甚么不输出
}
})
})
}
调用
//第一种ajax
util.$request("http://120.76.31.111/app/XhlGetSubjectTypeList",
"get",function(res){
console.log(res);
})
//用promise方法请求
util.promiseAjax('http://120.76.31.111/app/XhlGetSubjectTypeList', 'get').then(function (res) {//then:表示等待,等待完之后执行后面的函数
wx.hideLoading();//数据请求成功的时候隐藏loading
console.log("promise");
console.log(res);
wx.showToast({
title: '成功',
//success 显示成功图标,此时 title 文本最多显示 7 个汉字长度
icon: "success",
deration: 3000
})
})
Promise.all和Promise.race区别,和使用场景
一、Pomise.all的使用
常见使用场景 : 多个异步结果合并到一起
Promise.all可以将多个Promise实例包装成一个新的Promise实例。用于将多个Promise实例,包装成一个新的Promise实例。
1.它接受一个数组作为参数。
2.数组可以是Promise对象,也可以是其它值,只有Promise会等待状态改变。
3.当所有的子Promise都完成,该Promise完成,返回值是全部值的数组。
4.如果有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果。
Promise.all([p1,p2,p3])
先举例之前我们 如果有多个异步请求,但是最终用户想要得到的是 多个异步结果合并到一起,用之前代码举例
console.log('start');
var result1,result2="";
//settimeout 模拟异步请求1
setTimeout(() => {
result1="ok1"
}, 2000);
//settimeout 模拟异步请求2
setTimeout(() => {
result1="ok2"
}, 3000);
//等待 异步1 异步2结果
var tempInterval= setInterval(()=>{
if(result1&&result2){
console.log('data result ok ,,, clearInterval')
clearInterval(tempInterval);
}
},100)
使用Promise.all来解决 ,上代码
Promise.all可以将多个实例组装成一个新的实例,成功的时候返回一个成功数组,
失败的时候则返回最先被reject失败状态的值
比如当一个页面需要在很多个模块的数据都返回回来时才正常显示,比如当数组里的P1,P2、P3都执行完成时,页面才显示。,否则loading
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promse.reject('失败')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
//值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P3、p2
二、Pomise.race的使用
race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败
类似于Promise.all() ,区别在于 它有任意一个返回成功后,就算完成,但是 进程不会立即停止
常见使用场景:把异步操作和定时器放到一起,如果定时器先触发,认为超时,告知用户
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功了')
}, 2000);
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 5000);
})
Promise.race([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
一般用于和定时器绑定,比如将一个请求和一个三秒的定时器包装成Promise实例,加入到race队列中,请求三秒中还没有回应时,给用户一些提示或一些相应的操作。
const promise = new Promise(function(resolve, reject) {
let _resolve;
//resolve是一个方法,该方法可以继续传Promise实例进去,也可以把数据resolve出去
_resolve = resolve;
_resolve(new Promise((resolve, reject) => {
console.log(2)
}));
console.log(resolve)
if (true){
resolve(1);//成功的回调把数据resolve出去,then接收处理
} else {
reject('error');
}
});
promise.then();
补充
const promise = new Promise(function(resolve, reject) {
let _resolve;
//resolve是一个方法,该方法可以继续传Promise实例进去,也可以把数据resolve出去
_resolve = resolve;
_resolve(new Promise((resolve, reject) => {
// console.log(2)
}));
// console.log(resolve)
if(true) {
resolve(1); //成功的回调把数据resolve出去,then接收处理
} else {
reject('error');
}
});
promise.then();
不带有任何参数
Promise.resolve() 会直接返回一个promise((resolve, reject)=>{
}) Promise实例
参数不是具有then方法的对象,或根本就不是对象
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
//有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
//所以可以
Promise.resolve('foo').then(res=>{
console.log(res)
})
参数是一个thenable对象
thenable对象指的是具有then方法的对象,比如下面这个对象
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
//Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
//thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42
vuex dispatch的返回值 + Promise commit没有返回值
actions: {
ceshi(state) {
return new Promise((resolve, reject) => {
let a = 1;
console.log(a)
resolve(a)
})
}
},
async ceshi() {
await this.$store.dispatch('ceshi').then(res => {
console.log(res)
});
},
不用then,等同
async ceshi() {
let getInfoResult = await this.$store.dispatch('ceshi')
console.log('getInfoResult', getInfoResult);
},