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