您好,登錄后才能下訂單哦!
今天小編給大家分享一下async-await消滅異步回調的方法的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
async函數返回一個 Promise 對象,可以使用then方法添加回調函數。舉例說明:
// async返回的是Promise對象? async function testAsync() { return 'hello';//上篇文章Promise對象的返回值如果不是Promise,會通過Promise.resolve()轉化為Promise,再進行處理 } const result = testAsync() console.log(result);//Promise { 'hello' } 說明async返回的是Promise對象
那既然async返回的是Promise對象,那么async后面的函數可以接.then()或者.catch()...嘛?我們試一試就知道了。
// async返回的是Promise對象,并且可以接Promise的方法? async function testAsync() { // await await等待還是promise對象 return 'hello' } testAsync() .then((result)=>{ console.log(result); }) .catch((error)=>{ console.log(error); }) //hello 媽耶!打印了!說明async返回的是Promise對象,并且可以接Promise的方法,并且!!!默認狀態是resolved的
上面代碼說明,async函數內部return語句返回的值,會成為then方法回調函數的參數
當async函數內部拋出錯誤的時候,會導致返回的 Promise 對象變為reject狀態。拋出的錯誤對象會被.then()方法的第二個回調函數接收或者.catch()方法回調函數接收到。
// async函數內部拋出錯誤或者Promise狀態為reject async function testError(){ //throw new Error('出錯啦~~'); await Promise.reject('出錯了');//await前面有return和沒有return效果一樣 } testError() // .then(()=>{},(error)=>{console.log(error);}) .catch(error=>{console.log(error);}) //Error: 出錯啦~~
await命令后面是一個 Promise 對象,返回該對象的結果。如果不是 Promise 對象,就直接返回對應的值。代碼說明:
// await async function getName(){ // return '來自星星的你'; return await '來自星星的你';//上面直接return等價于這個return } getName() .then(result=>{console.log(result);}) //來自星星的你
await的使用,必須要有async。這便是async-await的浪漫所在了:async返回的是一個Promise對象,await等待的就是這個Promise對象,所以await不能沒有async(但是async可以沒有await)。有沒有被浪漫到?反正我是醉了。如果await沒有async會怎么樣?報錯:
// await沒有async會報錯 function testAwait(){ return await '西紅柿炒辣椒' } testAwait() .catch(error=>{ console.log(error); }) //SyntaxError: await is only valid in async function
// async封裝Promise async function fn1() { return '喜羊羊與灰太狼';// //相當于return Promise.resolve('喜羊羊與灰太狼') const data = await fn1();//接收data值 } fn1()//執行async函數,返回的是一個Promise對象 .then(data => { console.log('content =', data) }) //content = 喜羊羊與灰太狼
// await---.then() async function getName(){ const operate=Promise.resolve('白雪公主')//執行函數 const name= await operate //await相當于Promise的then operate.then(name=>{}) console.log('name:',name) } getName(); ( async function(){ const person=await '七個小矮人' //await Promise.resolve('七個小矮人') await后面不跟Promise,也會被封裝成Promise console.log('person:',person)//400 })();//自執行函數 //name: 白雪公主 //person: 七個小矮人
當函數執行的時候,一旦遇到await就會先返回,等到異步操作完成,再接著執行函數體內后面的語句。任何一個await語句后面的 Promise 對象變為reject狀態,那么整個async函數都會中斷執行。
async function testOrder() { await Promise.reject('出錯了')//UnhandledPromiseRejectionWarning: 出錯了 await Promise.resolve('hello world'); // 不會執行 } testOrder();
如果希望即使前一個異步操作失敗,也不要中斷后面的異步操作。可將第一個await放在try...catch結構里面,這樣不管這個異步操作是否成功,第二個await都會執行。
// try...catch !(async function () { const testError = Promise.reject('出錯啦~~~')//rejected狀態 // const testError=throw new Error('出錯啦~~~'); try { const result = await testError; //await相當于then,但是reject不會觸發then console.log('success:'+result) //不會輸出,因為const result = await testError被報錯,被catch捕獲 } catch (error) { console.error('error:'+error)//try...catch 相當于Promise的catch } })() //error:出錯啦~~~
當await后面是Promise對象的時候,我們也可直接在await后面直接.catch捕獲錯誤:
async function testError() { await Promise.reject('出錯了') .catch(error => console.log(error));//這里捕獲錯誤,不會影響下一個await執行 return await Promise.resolve('hello world'); } testError() .then(result => console.log(result))
我們淺淺看一個面試題:
// 面試題 function getJSON() { return new Promise((resolve, reject) => { setTimeout(() => { console.log(2); resolve(2) }, 2000) }) } async function testAsync() { await getJSON() console.log(3); } testAsync() //2 //3
問題當然不會問打印順序啦,問題是將async await語句解析翻譯為Promise?
根據現在的知識面,我們必須知道:
(1)await不能單獨出現,其函數前面一定要有async。
(2)await會干兩件事:
第一,將寫在await后面的代碼放到async創建的那個Promise里面執行。
第二、將寫在await下面的代碼放到前一個創建的那個Promise對象的.then里面執行。
(3)await返回的也是Promise對象,他只是把await下面的代碼放到了await返回的promise的.then里面執行。
這樣的話,是不是如魚得水了。翻譯如下:
function getJSON() { return new Promise((resolve, reject) => { setTimeout(() => { console.log(2); resolve(2) }, 2000) }) } // 編譯成Promise原理 function testAsync() { return Promise.resolve().then(() => { return getJSON(); }) .then(() => { console.log(3); }) } testAsync()
你學廢async-await了嘛?還記得上一篇開篇的回調地獄嘛?我們通過Promise解決回調是這樣的:
// Promise解決方式 function doCallback(n) { var myPromise = new Promise(function (resolve, reject) { //處理異步任務 var flag = true; setTimeout(function () { if (flag) { resolve(n) } else { reject('失敗') } },0) }) return myPromise; } doCallback(1) .then((result) => { //then是成功執行的方法 返回的還是一個Promise對象 console.log(result);//打印張三 res是執行 return fn(2); }) .then((result) => { console.log(result); return fn(3) }) .then((result) => { console.log(result); return fn(4) }) .then((result) => { console.log(result); }) .catch((result) => { //catch是失敗執行的方法 console.log(result); }) //好多.then,形成.then鏈啦 //1 //2 //3 //4
通過以上Promise方法,可以明顯解決回調地獄“向右移”的浮夸表現,但是,Promise是基于 then, catch 的鏈式調用,但也是基于回調函數。.then鏈多多少少還是違背原生代碼,顯得也不是很優雅。作為回調終極武器,async-await更加貼近于原生代碼,我們看一下吧:
//封裝一個返回promise的異步任務 function doCallback(str) { var myPromise = new Promise(function (resolve, reject) { var flag = true; setTimeout(function () { if (flag) { resolve(str) } else { reject('處理失敗') } }) }) return myPromise; } //封裝一個執行上述異步任務的async函數 async function testAsync() { var result1 = await doCallback(1); //await直接拿到fn()返回的promise的數據,并且賦值給result var result2 = await doCallback(2); //await 后面的代碼,都可以看做是異步回調 callback 里的內容,都是異步的 var result3 = await doCallback(3); var result4 = await doCallback(4); console.log(result1); console.log(result2); console.log(result3); console.log(result4); }//這樣是不是簡潔優雅多了呢? //執行函數 testAsync(); //1 //2 //3 //4
以上就是“async-await消滅異步回調的方法”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。