摘要:入门之基本用法背景在我们使用异步函数比如进行编写代码,如果我们需要很多个请求不同的接口,而下一个接口需要依赖上一个接口的返回值,这样,我们的代码则需要在各种回调函数中嵌套,这样一层一层地下去,就形成了回调地狱。
Promise入门之基本用法 背景
在我们使用异步函数比如ajax进行编写代码,如果我们需要很多个ajax请求不同的接口,而下一个接口需要依赖上一个接口的返回值,这样,我们的代码则需要在各种回调函数中嵌套,这样一层一层地下去,就形成了回调地狱。
但是promise的出现则不需要嵌套就能解决这个问题。什么是promise?promise本质其实是一个对象,用于传递异步操作的信息。并且promise这个对象提供了相对应的API,满足我们的需求开发。
</>复制代码
let pro = new Promise(function(resolve, reject){
// 异步处理逻辑
// 处理完毕之后调用resolve或者reject
})
promise对象跟其他普通对象的创建方法一样,只需要new一个新的对象即可,接受一个函数作为参数,并且该函数中的参数分别为两个回调函数,用于进行不同的逻辑处理。
在定完一个promise对象之后,我们可以通过调用then方法来执行其对应的逻辑
</>复制代码
pro.then(function(res){
// 如果promise对象调用了resolve方法,则进入该函数逻辑
}, function(err){
// 如果promise对象调用了reject方法,则进入该函数逻辑
})
promise的状态
promise的实例主要有以下三种状态:
①pending: 处理中
②fulfilled: 成功
③rejected: 失败
pending状态的promise可以转化为fulfilled状态或者rejected状态,该转化不可逆且只能转化一次。同时,fulfilled状态和rejected状态只能由pending状态转化,相互不能转化。如图
pending状态下的promise在处理完业务逻辑,且能正常退出时便可以执行resolve方法,从而进入fulfilled状态;
若pending状态下的promise在处理业务逻辑的过程中出现异常错误,或者主动调用reject方法,则进入rejected状态。
</>复制代码
let pro = new Promise(function(resolve, reject){
if(// 逻辑处理完毕且能正常退出){
resolve()
}
else{
// 异常错误抛出
reject()
}
})
pro.then(function(res){
// 如果promise对象调用了resolve方法,则进入该函数逻辑
}, function(err){
// 如果promise对象调用了reject方法,则进入该函数逻辑
})
链式调用
因为promise对象中的then方法的返回值是一个新的promise对象,因此可以实现链式调用。但后一个then方法的执行必须等待前一个then方法返回的promise对象状态转为fulfilled或者rejected,若promise对象处于pending状态下,则后一个then方法只能等待。
</>复制代码
pro.then(function(res){
// 第一个promise对象逻辑执行
return newPro;// 返回一个新promise
}).then(function(res){
// 对newPro这个对象进行处理
})
// ...可以一直链式调用下去
异常捕捉
promise中的catch方法其实就是pro.then(null, rejection),用户捕捉代码运行中的错误异常。
</>复制代码
pro.then(function(res){
// 逻辑处理,但存在异常
}).catch(function(err){
// 捕捉上一个then函数中所出现的异常错误
})
此外,catch方法的所捕捉的异常不仅仅局限于上一个then方法内,而是可以把错误一直传递下来,直至遇到的第一个catch,然后被捕捉。如链式调用中:
</>复制代码
pro.then(function(res){
// 逻辑处理,但存在异常
}).then({
// 逻辑处理
}).catch(function(err){
// 捕捉上面第一个出现异常的then函数中所出现的错误
})
promise.all
promise.all方法可以接受一个由promise组成的数组作为参数,包装成一个新的promise对象,并且按照数组中promise的顺序进行异步执行。如:
</>复制代码
let pro1 = new Promise(function(resolve, reject){});
let pro2 = new Promise(function(resolve, reject){});
let pro3 = new Promise(function(resolve, reject){});
let proAll = promise.all([pro1, pro2, pro3]);
proAll的状态由pro1,pro2,pro3三者共同决定:
①pending: 处理中,pro1,pro2,pro3中无rejected且存在pending状态。
②rejected: pro1,pro2,pro3中存在一个rejected。
③fulfilled:pro1,pro2,pro3三者均为fulfilled。
当proAll的状态为fulfilled时,会返回一个数组,该数组中的元素则是上面由promise组成的数组相对应执行后的结果。
promise.racepromise.race所接受的参数与promise.all一致,但promise.race的返回值则是由pro1,pro2,pro3三者中最先完成的promise对象决定,并且返回值为该最早完成的promise对象的返回值。
</>复制代码
let proAll = promise.race([pro1, pro2, pro3]);
promise.resolve
promise.resolve方法能将一个对象转换成promise对象
</>复制代码
let newPro = promise.resolve(obj);
①若obj不具有then方法,则newPro直接变为fulfilled状态
</>复制代码
let newPro = promise.resolve("i am not a promise");
newPro.then(function(str){
console.log(str) // 输出 i am not a promise
})
②如果obj本就是一个Promise对象,则promise.resolve会将obj直接返回。
promise.rejectpromise.reject方法与promise.resolve一样,能将一个对象转换成promise对象,但返回的promise对象的状态为rejected。
async/awaitasync是关键词,在一个函数名之前加上该关键词,表明该函数内部有异步操作,而这异步操作应该返回一个promise对象,并且在这异步操作之前添加await关键词。当函数执行的时候,遇到await则会先进行Promise的逻辑处理,带promise的状态不再为pending时再执行该函数后面的语句。
</>复制代码
let pro = new Promise(function(resolve, reject){
// 异步处理逻辑
resolve();
})
async function asyncFunc(){
// 正常执行的语句
await pro;
// 等待promise处理完之后再执行的语句
}
asyncFunc();
总结
promise的出现,为我们编写异步函数定下不少规则,在优化我们代码的同时也能减少代码量,并增强可读性,但也需严格遵守promise/A+的规范进行promise的开发。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/103095.html
摘要:是异步编程的另一种解决方案函数是对函数的改进的基本用法函数函数返回一个实例,可以使用方法为返回的实例添加回调函数。函数内部语句返回的值,会成为方法回调函数的参数。也就是说,只有函数内部的异步操作执行完,才会执行方法指定的回调函数。 async await async await是异步编程的另一种解决方案 async函数是对Generator函数的改进 async的基本用法 asyn...
摘要:现在我们要用的重点就是我们的,这是一个能让函数并行的,可以基于多个。非常有用啊先上一个错误的代码这时候我们得到的就是数字了,而不是一个数组,这就是神奇所在。 看过 (一)的同学一定觉得这个Promise很简单,好像没什么可以用的地方,但是事实上,它的用处非常大啊,尤其是在nodejs上,愈加重要,虽然已经有大量的库实现了对Promise的封装了,不过我还是更倾向用原生的node来实现对...
阅读 2896·2021-09-24 10:34
阅读 1998·2021-09-22 10:02
阅读 2388·2021-09-09 09:33
阅读 1551·2021-08-13 15:02
阅读 3397·2020-12-03 17:10
阅读 1280·2019-08-30 15:44
阅读 2243·2019-08-30 12:58
阅读 3323·2019-08-26 13:40
极致性价比!云服务器续费无忧!
Tesla A100/A800、Tesla V100S等多种GPU云主机特惠2折起,不限台数,续费同价。
NVIDIA RTX 40系,高性价比推理显卡,满足AI应用场景需要。
乌兰察布+上海青浦,满足东推西训AI场景需要