JavaScript中的同步方法及異步方法示例代碼
1.代碼說(shuō)明
const saveTem = () => {
// 校驗(yàn)處理
const res = check()
if (!res) {
return
}
addTemplateRef.value.openModal()
}這段代碼中,check方法返回的是true和false,是一個(gè)普通方法,
openModal也是一個(gè)普通方法,沒(méi)有返回值,
這段代碼的執(zhí)行順序是依次執(zhí)行的,因?yàn)闆](méi)有任何異步操作,即使這個(gè)方法被async修飾,代碼的執(zhí)行順序也是依次執(zhí)行的
什么是異步操作,可以簡(jiǎn)單理解為方法被async修飾,axios及fetch請(qǐng)求及setTimeout方法等。
返回值為promise的方法不一定為異步方法,也就是說(shuō)異步方法不能通過(guò)返回值進(jìn)行判斷
但是異步方法的返回值一定是promise,必須使用await或者.then才能獲取實(shí)際返回值
2.async修飾的方法和非async修飾的方法的區(qū)別
1. 返回值不同
async 函數(shù):
總是返回一個(gè) Promise 對(duì)象
如果返回非 Promise 值,會(huì)自動(dòng)用 Promise 包裝
如果拋出異常,返回被拒絕(rejected)的 Promise
普通函數(shù):
直接返回 return 語(yǔ)句指定的值
如果沒(méi)有 return,返回 undefined
拋出異常會(huì)直接中斷執(zhí)行
2. 執(zhí)行方式不同
async 函數(shù):
內(nèi)部可以使用 await 暫停執(zhí)行,使用await后會(huì)等待后面的方法執(zhí)行完成,再繼續(xù)后續(xù)的內(nèi)容
不會(huì)阻塞主線程
普通函數(shù):
同步執(zhí)行
會(huì)阻塞后續(xù)代碼直到執(zhí)行完成
async function asyncFunc() {
console.log(1);
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(2);
}
function syncFunc() {
console.log(1);
setTimeout(() => console.log(2), 1000);
console.log(3);
}
asyncFunc(); // 輸出: 1, 2 (1秒后)
syncFunc(); // 輸出: 1, 3, 2 (1秒后)3. 錯(cuò)誤處理不同
async 函數(shù):
拋出的錯(cuò)誤會(huì)被捕獲并轉(zhuǎn)換為 rejected Promise
需要使用 try/catch 或 .catch() 捕獲錯(cuò)誤
普通函數(shù):
錯(cuò)誤會(huì)直接拋出
需要使用 try/catch 捕獲同步錯(cuò)誤
4. 調(diào)用方式不同
async 函數(shù):
必須用 await 或 .then() 才能獲取結(jié)果
直接調(diào)用會(huì)返回 Promise 對(duì)象而非實(shí)際結(jié)果
普通函數(shù):
直接調(diào)用獲取返回值
5. 適用場(chǎng)景
使用 async 函數(shù)的場(chǎng)景:
需要處理 Promise 鏈?zhǔn)秸{(diào)用,使用之前的.then會(huì)導(dǎo)致回調(diào)地獄問(wèn)題,使用await可以讓多個(gè)異步操作按照順序執(zhí)行,使代碼更加整潔
需要順序執(zhí)行多個(gè)異步操作
需要更清晰的異步代碼結(jié)構(gòu)
使用普通函數(shù)的場(chǎng)景:
純同步操作
示例
async function getData() {
console.log('開(kāi)始獲取數(shù)據(jù)...'); // 1. 同步執(zhí)行
const result = await fetchData(); // 2. 遇到 await,暫停執(zhí)行并等待 Promise 解決
console.log(result); // 4. Promise 解決后繼續(xù)執(zhí)行
return result; // 5. 返回結(jié)果(包裝在 Promise 中)
}
// 模擬異步函數(shù)
function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve('數(shù)據(jù)獲取成功'), 1000); // 3. 1秒后解決 Promise
});
}
// 調(diào)用示例
getData().then(data => console.log('最終結(jié)果:', data)); // 6. 接收最終結(jié)果詳細(xì)執(zhí)行流程:
同步階段:
調(diào)用 getData() 函數(shù)
執(zhí)行第一行
console.log('開(kāi)始獲取數(shù)據(jù)...')(立即輸出)
遇到 await:
執(zhí)行 fetchData()(返回一個(gè) Promise)
await 會(huì)暫停
getData()函數(shù)的執(zhí)行,將控制權(quán)交回事件循環(huán)此時(shí)
getData()返回一個(gè)未解決的 Promise,pending狀態(tài)的promise
異步等待:
fetchData()中的setTimeout開(kāi)始計(jì)時(shí)(1秒)JavaScript 引擎可以處理其他任務(wù)
Promise 解決:
1秒后,
setTimeout回調(diào)執(zhí)行,Promise 被解決(resolve)await接收到解決的值'數(shù)據(jù)獲取成功'getData()函數(shù)恢復(fù)執(zhí)行
繼續(xù)執(zhí)行 async 函數(shù):
將解決的值賦給
result執(zhí)行
console.log(result)(輸出 "數(shù)據(jù)獲取成功")執(zhí)行
return result(這里會(huì)包裝成一個(gè)promise)
處理最終結(jié)果:
.then()回調(diào)被執(zhí)行,輸出 "最終結(jié)果: 數(shù)據(jù)獲取成功"
關(guān)鍵點(diǎn)說(shuō)明:
await會(huì)暫停當(dāng)前 async 函數(shù)的執(zhí)行(但不會(huì)阻塞主線程)async 函數(shù)在遇到第一個(gè)
await時(shí)就會(huì)立即返回一個(gè) Promise被暫停的函數(shù)會(huì)在 Promise 解決后從暫停點(diǎn)繼續(xù)執(zhí)行
return 的值會(huì)自動(dòng)包裝成 Promise
3.不使用await的場(chǎng)景
場(chǎng)景 1:明確需要 Promise 對(duì)象時(shí)
const fetchData = async () => { /* ... */ };
// 需要傳遞 Promise 給其他邏輯
const promise = fetchData(); // 不 await,保留 Promise
promise.then((data) => { /* ... */ });場(chǎng)景 2:并行多個(gè)異步任務(wù)(用 Promise.all)
const getUser = async () => { /* ... */ };
const getPosts = async () => { /* ... */ };
// 不單獨(dú) await,直接收集 Promises
const [user, posts] = await Promise.all([getUser(), getPosts()]);關(guān)鍵點(diǎn)說(shuō)明
并行執(zhí)行:
getUser()和getPosts()會(huì)同時(shí)開(kāi)始執(zhí)行,而不是一個(gè)接一個(gè)執(zhí)行。Promise.all 的作用:
接收一個(gè) Promise 數(shù)組作為輸入
返回一個(gè)新的 Promise,當(dāng)所有輸入的 Promise 都解決(resolve)時(shí),這個(gè)新 Promise 才會(huì)解決
解決值是一個(gè)數(shù)組,包含所有輸入 Promise 的解決值,順序與輸入數(shù)組一致
解構(gòu)賦值:
const [user, posts] = ...將 Promise.all 返回的數(shù)組解構(gòu)為兩個(gè)變量
執(zhí)行流程
調(diào)用
getUser()和getPosts()會(huì)立即返回兩個(gè) Promise 對(duì)象這兩個(gè)異步操作會(huì)同時(shí)開(kāi)始執(zhí)行(假設(shè)它們不互相依賴)
Promise.all會(huì)等待這兩個(gè) Promise 都完成當(dāng)兩者都完成后,結(jié)果會(huì)被解構(gòu)到
user和posts變量中
與順序執(zhí)行的對(duì)比
如果寫(xiě)成這樣就是順序執(zhí)行(不推薦):
const user = await getUser(); // 等待這個(gè)完成 const posts = await getPosts(); // 然后才開(kāi)始這個(gè)
而使用 Promise.all 的方式總耗時(shí)大約等于較慢的那個(gè)操作的時(shí)間,而不是兩者時(shí)間相加。
注意事項(xiàng)
如果其中一個(gè) Promise 被拒絕(reject),整個(gè)
Promise.all會(huì)立即拒絕適合用于彼此獨(dú)立的異步操作
如果操作之間有依賴關(guān)系,可能需要順序執(zhí)行
4.總結(jié)
方法中如果沒(méi)有異步方法,按照順序依次執(zhí)行
如果有異步方法,沒(méi)有使用await或者.then,不會(huì)依次執(zhí)行,會(huì)先執(zhí)行異步方法后面的方法,再執(zhí)行異步方法
如果需要控制方法內(nèi),異步方法的順序,可以使用await或者.then,需要注意如果要使用await,則方法必須被async修飾
使用async修飾的方法,返回值為promise,需要使用await或者.then獲取返回值
返回值為promise不一定是異步方法,異步方法的返回值一定是promise
常見(jiàn)的異步方法為async修飾的方法,setimeout方法,axios方法,fetch方法
到此這篇關(guān)于JavaScript中的同步方法及異步方法的文章就介紹到這了,更多相關(guān)js同步方法及異步方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js調(diào)用activeX獲取u盤(pán)序列號(hào)的代碼
js調(diào)用activeX獲取u盤(pán)序列號(hào)的代碼,需要的朋友可以參考下。2011-11-11
將數(shù)字轉(zhuǎn)換成大寫(xiě)的人民幣表達(dá)式的js函數(shù)
將數(shù)字轉(zhuǎn)換成大寫(xiě)的人民幣,方法有很多,本例介紹的是使用js來(lái)完成的,有需要的朋友可以參考下2014-09-09
基于JavaScript實(shí)現(xiàn)移動(dòng)端點(diǎn)擊圖片查看大圖點(diǎn)擊大圖隱藏
最近接了個(gè)項(xiàng)目,項(xiàng)目需求是這樣的,當(dāng)點(diǎn)擊圖片查看圖片,再次點(diǎn)擊大圖被隱藏,在移動(dòng)端用的比較多,因?yàn)橐苿?dòng)端屏幕小,需要查看大圖。具體代碼實(shí)現(xiàn)過(guò)程本文給大家介紹,需要的朋友可以參考下2015-11-11
JavaScript實(shí)現(xiàn)點(diǎn)擊切換功能
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊切換功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01
JS 中LocalStorage和SessionStorage的使用
最近因?yàn)轫?xiàng)目上需要使用到客戶端存儲(chǔ),所以稍微研究了一下,以下說(shuō)說(shuō)自己的理解和使用經(jīng)驗(yàn),特此分享到腳本之家平臺(tái),感興趣的朋友參考下吧2017-08-08
JavaScript實(shí)現(xiàn)自動(dòng)跳轉(zhuǎn)文本功能
這篇文章主要為大家詳細(xì)介紹了JavaScript自動(dòng)跳轉(zhuǎn)文本功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05

