1 promise 是什么
2async和await的原理以及具体用法
3 async和await和promise区别
4 axios 对象的讲解
5 使用 try,catch优雅的处理异常
6setTimeoute,Promise,async 三者的执行顺序
7await is a reserved word 问题解决方式
8for循环中使用 async和await
1promise
axios,async,await 这几个项目中常用到的处理异步,其实都和promise对象有关。接下来我们讲解一下什么是promise对象,在浏览器上面输出一下 Promise对象
可以看到,Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。这么说用Promise new出来的对象肯定就有then、catch方法喽,没错。
这里先讲解一下最简单的promise理解,我们可以在new Promise的参数体中,进行一些异步的操作,比如http请求后端接口,当拿到数据的时候,再使用resolve(res)将得到的数据回调出来,这样在promise.then(function(data){}) 这里的data,就是上面resolve(res)中的res。
var p = new Promise(function(resolve, reject){
//这里做一些异步的操作,比如http请求,拿到数据之后,resolve,这样。then的回调函数函数,就会拿到resolve传递过来的数据
setTimeout(function(){
console.log('这里使用setTimeout模拟http请求,进行异步操作');
if(isTrue){
//模拟http请求成功,则resolve 接口数据,然后promise会调用then得到数据
resolve('张三');
}else if(isFalse){
//模拟http请求失败,则reject错误数据。然后promise会调用cathc得到错误数据
reject('失败操作');
}
}, 2000);
});
//此处调用.then一定是**promise对象**,所以如果是一个方法,然后返回一个promise对象,也可以使用.then方法
//比如 returnPromise().then(res=>{});
// function returnPromise(){
// return new Promise()
// }
p.then(function(data){
console.log('data'); //张三
}).catch(function(errr){
console.log(err); //'失败操作'
});
promise还有一个链式操作,主要用于处理多个嵌套的问题。比如下面
function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
}
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return '直接返回数据'; //这里直接返回数据
})
.then(function(data){
console.log(data);
});
2 async和await主要用于处理异步问题,但他的本质还是promise。当我们在函数前面加上 async时,该函数就会变成一个异步的函数。并且会返回一个promise对象。既然是Promise对象,他就拥有promise对象的所有特点。await关键字表示等待,他后面的变量,是一个promise变量(有时候我们可以看到是使用一个方法,因为该方法也是返回一个promsie对象)。等待后面promise对象resolve返回数据的时候,await对应的语句就会被执行,拿到resolve(res)返回的res数据
function getData(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
var userName=“张三”;
resolve(userName);
},1000);
})
}
async fucntion test(){
//因为await会面跟着的,是promise对象,所以只要是promsie对象,写成返回方法也行
//这里也可以写成async 声明的函数对象,因为async声明的函数,返回的也是promise对象
var data=await getData();
console.log(data);
}
async function getData(){
return '**这是一个数据'**
};
async function test(){
var d=await getData();
console.log(d); // **这是一个数据'**
}
test()
3async,await处理异步和promise处理异步的区别
1 async,await处理可以不用理会then,但是promise想得到resolve 数据,必须使用then回调
2Async/Await与Promise最大区别在于:await b()会暂停所在的async函数的执行;而Promise.then(b)将b(这里b是一个回调函数)函数加入回调链中之后,会继续执行当前函数。对于堆栈来说,这个不同点非常关键。 这两种语法最大的区别是:无论是await或者是Promise,他们都是把相应的函数加入异步队列中,但是不会影响主线程的继续加载,不会阻塞程序进程。
4 axios 对象的讲解
axios是一个基于promise的HTTP库,简单来说,axios就是对promise进行了一次封装。我们能够在项目中更方便的发送HTTP请求.他有then 也有 catch回调参数
axios.get('localhost:8090/springboot_jpa/student/findAll').then(res => {
this.studentList = res.data
console.log(res)
}).catch(err => {
console.log(err)
})
5 使用 try,catch优雅的处理异常
例子:
async updateArticleById(ctx, next){
let id = ctx.params["id"];
let body = ctx.request.body;
try {
let ret = await Services.admin.updateArticle(id, body);
ctx.body = {ret: 0, data: ret};
} catch(e) {
ctx.body = {ret: 1, data: null, err: e.message || e.stack};
}
}
捕获异常通常是使用try/catch的方式来处理,因为await后面跟着的是Promise对象,当有异常的情况下会被Promise对象的内部catch捕获,而await就是一个then的语法糖,并不会捕获异常(await返回的对象,并没有 .then 和.catch的方法), 那就需要使用try/catch来捕获异常,并进行相应的逻辑处理。单如果存在多个await,就需要编写多个try catch,就会使得代码变得非常不优雅。这里我们建议封装一个方法
module.exports = (promise) => {
if(!promise || !Promise.prototype.isPrototypeOf(promise)){
return new Promise((resolve, reject)=>{
reject(new Error("requires promises as the param"));
}).catch((err)=>{
return [err, null];
});
}
return promise.then(function(){
return [null, ...arguments];
}).catch(err => {
return [err, null];
});
};
格式[error, …result]
采用类似Golang风格的错误返回方式, 这里指定第一个参数为错误参数,后面为正常返回结果
if块是用来处理非法参数,并返回错误[err, null]
await后面如果是一个promise对象,那么await的任务就是在等待promise.resolve,
而to.js就是主动去调用then和catch,主动处理并重新封装结果,并且在then或是catch里面继续返回封装后的数据,
返回值对于await来说仍然是一个promise对象,然而resolve的值却是一个可迭代的对象[error, …result]
这个可迭代的对象如何使用
async updateArticleById(ctx, next){
let body = ctx.request.body;
let id = ctx.request.params["id"];
let [err, ret] = await ctx.app.utils.to(Services.admin.updateArticleById(id, body));
if(err) {
return ctx.body = {ret: 1, data: null, err: err};
}
ctx.body = {ret: 0, data: ret};
}
6setTimeoute,Promise,async 三者的执行顺序
页面执行过程包含主线程还有任务队列。异步执行的js代码,会被放在任务队列中执行。但setTimeout,Promise,async 三者都会被存放在任务队列中,这样子这三个的执行顺序是什么?
1 ,在async里遇到await它会使async函数暂停执行,执行完async里的await内容后将后续的内容扔入到浏览器的任务队列里面去
async function async1(){
//这里执行完async1 start之后,会等待async返回的promise对象,当async返回成功之后,
// console.log('async1 end')不会执行,他会被存放到异步队列中
console.log('async1 start');
await async2();
console.log('async1 end');
}
2 下面这里,promise是立即执行的,所以promise1会立刻被输出,然后执行resolve()方法,之后.then中的console.log(promise2)会被存放到异步队列中
3这三个内容setTimeout会在最后执行,就好比css权重的优先级,大家固定记住就可以,setTimeout的优先级没有async和promise级别高(其实async和promise是一样的,因为调用async方法时就是返回一个promise对象)
而后async和promise的.then就看谁先进入到的任务队列里面,任务队列里面有先进先出的概念。所以结果很明显了,它们三个的输出顺序是:
https://www.cnblogs.com/SamWeb/p/8417940.html
https://blog.csdn.net/fundebug/article/details/81127760
https://segmentfault.com/a/1190000013624697
https://segmentfault.com/a/1190000011802045