ES6中的Promise、async、await
/* 二、什么是Promise(一) 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。 为了解决回调地狱的问题,出现了promise对象,*/ $.ajax({ url: 'https://xxxx/', type: 'POST', data: { username: 'sdsd', password: '123123' }, success: function (res) { $.ajax({ url: 'https://xxxxx', type: 'GET', succes: function (res) { $.ajax({ url: 'https://xxxxx', type: 'GET', data: { movieId: $(this).data('id') }, success: function (res) { var data = res.data; } }) } }); /* Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数: resolve :异步操作执行成功后的回调函数 reject:异步操作执行失败后的回调函数 */ let p = new Promise((resolve, reject) => { //做一些异步操作 setTimeout(() => { console.log('执行完成'); resolve('我是成功!!'); }, 2000); /* then 链式操作的用法 所以,从表面上看,Promise只是能够简化层层回调的写法,而实质上, Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用, 它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的 */ p.then((data) => { console.log(data); }) .then((data) => { console.log(data); }) .then((data) => { console.log(data); }); // reject的用法 :把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。看下面的代码。 let p = new Promise((resolve, reject) => { //做一些异步操作 setTimeout(function(){ var num = 6; if(num<=5){ resolve(num); } else{ reject('数字太大了'); } }, 2000); }); p.then((data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); } ); // then中传了两个参数,then方法可以接受两个参数,第一个对应resolve的回调, // 第二个对应reject的回调。所以我们能够分别拿到他们传过来的数据。 // catch的用法 // 我们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调。用法是这样: p.then((data) => { console.log('resolved',data); }).catch((err) => { console.log('rejected',err); }); // 效果和写在then的第二个参数里面一样。不过它还有另外一个作用: // 在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。请看下面的代码: p.then((data) => { console.log('resolved',data); console.log(somedata); //此处的somedata未定义 }) .catch((err) => { console.log('rejected',err); }); /* 在resolve的回调中,我们console.log(somedata);而somedata这个变量是没有被定义的。 如果我们不用Promise,代码运行到这里就直接在控制台报错了,不往下运行了。也就是说进到catch 方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能 */ /* 三、理解 JavaScript 的 async/await 任意一个名称都是有意义的,先从字面意思来理解。async 是“异步”的简写,而 await 可以认为是 async wait 的简写。所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。 用 setTimeout 模拟耗时的异步操作,先来看看不用 async/await 会怎么写*/ function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } takeLongTime().then(v => { console.log("got", v); }); //如果改用 async/await 呢,会是这样 function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } async function test() { const v = await takeLongTime(); console.log(v); } test(); //async/await 的优势在于处理 then 链 // promise方法 let p1 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p1') },4000) }) let p2 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p2') },200) }) let p3 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p3') },200) }) // 想让p1完成后再执行P2再执行P3 // 数量太多只能循环嵌套 p1.then((res) => { console.log(res); p2.then((res) => { console.log(res); p3.then((res) => { console.log(res); }) }) }) // async await语法糖 let a1=()=>{ return new Promise((resolve,reject) => { setTimeout(() => { resolve('我是a1') },4000) }) } let a2=()=>{ return new Promise((resolve,reject) => { setTimeout(() => { resolve('我是a2') },40) }) } let a3=()=>{ return new Promise((resolve,reject) => { setTimeout(() => { resolve('我是a3') },40) }) } // 想让a1完成后再执行a2再执行a3 //能避免回调 async function asy(){ await a1().then((res) => {console.log(res)}); await a2().then((res) => {console.log(res)}); await a3().then((res) => {console.log(res)}); } asy(); /*错误处理 在async函数里,无论是Promise reject的数据还是逻辑报错,都会被默默吞掉, 所以最好把await放入try{}catch{}中,catch能够捕捉到Promise对象rejected的数据或者抛出的异常 */ const makeRequest = () => { try { getJSON() .then(result => { // JSON.parse可能会出错 const data = JSON.parse(result) console.log(data) }) // 取消注释,处理异步代码的错误 // .catch((err) => { // console.log(err) // }) } catch (err) { console.log(err) } } const makeRequest = async () => { try { // this parse may fail const data = JSON.parse(await getJSON()) console.log(data) } catch (err) { console.log(err) } } const makeRequest = async () => { // this parse may fail const data = JSON.parse(await getJSON()).catch(err =>{ console.log(err) }) console.log(data) } } )
再忙也别忘记学习