站在巨人的肩膀上-Promise
Promise
Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才做,例如网络请求、读取本地文件等
Promise的三种状态
1.初始化,状态:pending
2.当调用resolve(成功),状态:pengding=>fulfilled
3.当调用reject(失败),状态:pending=>rejected
then 方法就是用来指定Promise对象的状态改变时确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)
构造一个Promise
Promise对象是一个构造函数,所以创建Promise时也要同Array,Object一样使用new命令,Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
Promise 做为函数的返回值
let fn = (flasg) =>{
return new Promise((resolve,reject) =>{
if(flasg === true){
resolve("Promise状态为成功")
};
if(flasg === false){
reject("Promise状态为失败")
}
})
}
console.log(fn(true)) // 状态为成功
console.log(fn(false)) // 状态为失败
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数:
let fnFun = (flasg) =>{
let judge = new Promise( (resolve,reject) =>{
if(flasg === true) {
resolve("Primise状态为成功")
}
if(flasg === false) {
reject("Primise状态为失败")
}
});
// judge 是一个promiseshi实例
judge.then(function(res) {
console.log( res,"res")
},
function(err){
console.log(err)
})
}
console.log(fnFun(true),"成功")
console.log(fnFun(false),"失败")
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数:
let promise = new Promise( function(resolve,reject){
console.log("promise"); // 先执行
resolve();
});
promise.then(() =>{
console.log("resovled") // 最后执行
})
console.log("Hi") // 同步结果
如果我们既要使用异步(使用异步会优先运行非异步的代码),又要使用异步函数改变的或者是获取的参数就会导致意想不到的错误:
function GetData(){
var data;
let promise = new Promise( (resolve,reject) =>{
resolve();
}).then( () =>{
// .then 里面的内容是最后才走的
data = {name:"校名"} // 2.没有定义
console.log("22222",data.name) // 1.打印data.name的值
return promise // 检测到promise#<promise>的链循环
})
}
GetData();
现在我们需要的方法是,先执行promise的异步操作后再执行后面的代码怎么办呢?--------------------为解决这一难题我们就需要后面的代码去“等待”--->await 解决方案: 调整一下顺序的解决方案 通常 await和async是同时使用的,await只能出现再async的内部:
解决方案一:
先执行promise的异步操作
后再执行后面的代码
async function getData(){
var data;
let promise = await new Promise( (resolve,reject) =>{
resolve();
}).then(() =>{
data = {name:"小红"};
console.log("44444",data.name) // 先执行.then 里面的内容再执行同步的内容
});
console.log(22222,data.name)
return promise
}
getData()
解决方案二直击项目:
methods: {
// 获取登录token
myLogin() {
// 使用异步处理先获取token 后再次执行其他操作
let myLogin = new Promise((resolve, reject) => {
uni.clearStorage()
uni.login({
provider: 'weixin',
success(res) {
let code = res.code
let params = {
code: code
}
// console.log(code,"code")
// return
apilogin.Reqloginfirst(params).then((res) => {
uni.setStorageSync('token', res.data.result.token)
if (res.data.result.user.operType == 0) {
uni.setStorageSync('operType', false)
} else {
uni.setStorageSync('operType', true)
}
if (res.data.result.user.mobile) {
uni.setStorageSync('mobile', true)
} else {
uni.setStorageSync('mobile', false)
}
resolve(uni.getStorageSync('token'))
})
},
fail(res) { }
})
})
return myLogin // 返回一个promise 对象结果
// #endif
console.log(1111)
},
LexicalFunHandle() {
//查询已关注的词条
let LexicalFunHandle = new Promise((resolve, reject) => {
apifoucs.Requserfocus().then((res) => {
let focusData = res.data.data
if (res.data.data.length <= 2) {
resolve(0) // 根据判断返回正确结果后判断值执行什么操作
} else {
resolve(1) // 根据判断返回正确结果后判断值执行什么操作
}
})
})
return LexicalFunHandle
},
toPages(topages) {
if (topages == 1) {
// 跳转到首页
uni.switchTab({
url: '/pages/DemoMins/index/index'
})
} else {
// 跳转选择词条页面
uni.navigateTo({
url: '/pages/lemmas/index'
})
}
},
// loginPage方法前面加了async,在promise前面加了await;代码的执行顺序就是依次执行;
async loginPage() {
let a = await this.myLogin() // 先执行登录
let topages = await this.LexicalFunHandle() // 在执行是否关注词条
this.toPages(topages) // 根据第二个执行的异步状态值返回值执行第三个方法
}
}
如上代码所示,我们在getData函数前面加了async,在promise前面加了await;代码的执行顺序就是依次执行; 我们可以在实际项目中,根据业务进行相关的依次顺序的执行方法!
可以理解为: 当执行到await时,代码异步执行,当执行完毕后,再执行其后的代码
Promise API
- 参数:接受一个数组,数组内都是
Promise
实例 - 返回值:返回一个
Promise
实例,这个Promise
实例的状态转移取决于参数的Promise
实例的状态变化。当参数中所有的实例都处于resolve
状态时,返回的Promise
实例会变为resolve
状态。如果参数中任意一个实例处于reject
状态,返回的Promise
实例变为reject
状态。
Promise.all([p1, p2]).then(function (result) { console.log(result);
// [ '2.txt', '2' ] });
不管两个promise谁先完成,Promise.all 方法会按照数组里面的顺序将结果返回
转载自:https://juejin.cn/post/7158371367123943431