日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Vue3,用組合編寫更好的代碼:AsyncWithoutAwait模式

?如果能讓異步代碼正確工作,它可以大大簡化我們代碼。但是,處理這種額外的復(fù)雜性,特別是與可合一起,可能會令人困惑。這篇文章介紹了無等待的異步模式。這是一種在組合中編寫異步代碼的方法,而不像通常那樣令人頭疼。

創(chuàng)新互聯(lián)是專業(yè)的伊川網(wǎng)站建設(shè)公司,伊川接單;提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行伊川網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

無等待的異步

用組合API編寫異步行為有時會很麻煩。所有的異步代碼必須在任何反應(yīng)式代碼之后的設(shè)置函數(shù)的末端。如果你不這樣做,它可能會干擾你的反應(yīng)性。

當(dāng)setup函數(shù)運(yùn)行到一個await語句時,它將返回。一旦它返回,該組件就會被掛載,并且應(yīng)用程序會像往常一樣繼續(xù)執(zhí)行。任何在await之后定義的響應(yīng)式,無論是 computed、watcher,還是其他什么,都還沒有被初始化。

這意味著,一個在await之后定義的計(jì)算屬性一開始不會被模板使用。相反,只有在異步代碼完成,setup 函數(shù)完成執(zhí)行后,它才會存在。

然而,有一種方法可以編寫異步組件,可以在任何地方使用,而不需要這些麻煩。

const count = ref(0);
// 這種異步數(shù)據(jù)獲取不會干擾我們的響應(yīng)式
const { state } = useAsyncState(fetchData());
const doubleCount = computed(() => count * 2);

實(shí)現(xiàn)沒有等待的異步模式

為了實(shí)現(xiàn)這一模式,我們將同步地掛起所有的響應(yīng)式值。然后,每當(dāng)異步代碼完成后,這些值將被異步更新。

首先,我們需要把我們的狀態(tài)準(zhǔn)備好并返回。我們將用一個null的值來初始化,因?yàn)槲覀冞€不知道這個值是什么。

export default useMyAsyncComposable(promise) {
const state = ref(null);
return state;
}

第二,我們創(chuàng)建一個方法,等待我們的 promise ,然后將結(jié)果設(shè)置為 state:

const execute = async () => {
state.value = await promise;
}

每當(dāng)這個promise 返回時,它就會主動更新我們的state。

現(xiàn)在我們只需要把這個方法添加到組合中。

export default useMyAsyncComposable(promise) {
const state = ref(null);

// Add in the execute method...
const execute = async () => {
state.value = await promise;
}

// ...and execute it!
execute();

return state;
}

我們在從useMyAsyncComposable方法返回之前調(diào)用了execute函數(shù)。然而,我們并沒有使用await關(guān)鍵字。

當(dāng)我們停止并等待execute方法中的 promise 時,執(zhí)行流立即返回到useMyAsyncComposable函數(shù)。然后它繼續(xù)執(zhí)行execute()語句并從可組合對象返回。

export default useMyAsyncComposable(promise) {
const state = ref(null);

const execute = async () => {
// 2. 等待 promise 執(zhí)行完成
state.value = await promise

// 5. 一段時間后...
// Promise 執(zhí)行完,state 更新
// execute 執(zhí)行完成
}

// 1. 執(zhí)行 `execute` 方法
execute();
// 3. await 將控制權(quán)返回到這一點(diǎn)上。

// 4. 返回 state 并繼續(xù)執(zhí)行 "setup" 方法
return state;
}

promise在后臺執(zhí)行,因?yàn)槲覀儧]有等待它,所以它不會在setup函數(shù)中中斷流。我們可以將此可組合放置在任何地方,而不影響響應(yīng)性。

讓我們看看 VueUse 中一些組合是如何實(shí)現(xiàn)這種模式的。

useAsyncState

useAsyncState 可以讓我們在任何地方執(zhí)行任何異步方法,并獲得響應(yīng)性的更新結(jié)果。

const { state, isLoading } = useAsyncState(fetchData());

在查看源代碼時,可以看到它實(shí)現(xiàn)了這種精確的模式,但具有更多的特性,并能更好地處理邊界情況。

下面是 useAsyncState 的一個簡化版:

export function useAsyncState(promise, initialState) {
const state = ref(initialState);
const isReady = ref(false);
const isLoading = ref(false);
const error = ref(undefined);

async function execute() {
error.value = undefined;
isReady.value = false;
isLoading.value = true;

try {
const data = await promise;
state.value = data;
isReady.value = true;
}
catch (e) {
error.value = e;
}

isLoading.value = false;
}

execute();

return {
state,
isReady,
isLoading,
error,
};
}

這個可組合的系統(tǒng)還返回isReady,告訴我們數(shù)據(jù)何時被取走。我們還得到了isLoading和error,以跟蹤我們的加載和錯誤狀態(tài)。

現(xiàn)在來看看另一個可組合,我認(rèn)為它有一個迷人的實(shí)現(xiàn)方式。

useAsyncQueue

如果傳給useAsyncQueue一個 promise 函數(shù)數(shù)組,它會按順序執(zhí)行每個函數(shù)。所以,在開始下一個任務(wù)之前,會等待前一個任務(wù)的完成。為了使用更靈活,它上一個任務(wù)的結(jié)果作為輸入傳給下一個任務(wù)。

const { result } = useAsyncQueue([getFirstPromise, getSecondPromise]);

下面是一個官網(wǎng)的例子:

const getFirstPromise = () => {
// Create our first promise
return new Promise((resolve) => {
setTimeout(() => {
resolve(1000);
}, 10);
});
};

const getSecondPromise = (result) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(1000 + result);
}, 20);
});
};

const { activeIndex, result } = useAsyncQueue([
getFirstPromise,
getSecondPromise
]);

即使它在異步執(zhí)行代碼,我們也不需要使用await。即使在內(nèi)部,可組合的程序也不使用await。相反,我們在 "后臺"執(zhí)行這些 promise,并讓結(jié)果響應(yīng)式更新。

讓我們看看這個組合是如何工作的。

// 初始一些默認(rèn)值
const initialResult = Array.from(new Array(tasks.length), () => ({
state: promiseState.pending,
data: null,
});

// 將默認(rèn)值變成響應(yīng)式
const result = reactive(initialResult);

// 聲明一個響應(yīng)式的下標(biāo)
const activeIndex = ref(-1);

主要的功能是由一個reduce來支持的,它逐個處理每個功能

tasks.reduce((prev, curr) => {
return prev.then((prevRes) => {
if (result[activeIndex.value]?.state === promiseState.rejected && interrupt) {
onFinished();
return;
}

return curr(prevRes).then((currentRes) => {
updateResult(promiseState.fulfilled, currentRes);
activeIndex.value === tasks.length - 1 && onFinished();
return currentRes;
})
}).catch((e) => {
updateResult(promiseState.rejected, e);
onError();
return e;
})
}, Promise.resolve());

Reduce 方法有點(diǎn)復(fù)雜,我們拆解一下,一個個看:

tasks.reduce((prev, curr) => {
// ...
}, Promise.resolve());

然后,開始處理每個任務(wù)。通過在前一個promise基礎(chǔ)上鏈接一個.then來完成這個任務(wù)。如果promise 被拒絕,就提前中止并返回。

if (result[activeIndex.value]?.state === promiseState.rejected && interrupt) {
onFinished();
return;
}

如果不提前終止,則執(zhí)行下一個任務(wù),并傳遞上一個 promise 的結(jié)果。我們還調(diào)用updateResult方法,將其添加到該組合返回的 result 數(shù)組中

return curr(prevRes).then((currentRes) => {
updateResult(promiseState.fulfilled, currentRes);
activeIndex.value === tasks.length - 1 && onFinished();
return currentRes;
});

正如你所看到的,該可組合實(shí)現(xiàn)了Async Without Await模式,但該模式只是整個可組合的幾行。所以它不需要很多額外的工作,只要記住把它放在適當(dāng)?shù)奈恢?/p>

總結(jié)

如果我們使用Async Without Await模式,我們可以更容易地使用異步組合。這種模式可以讓我們把異步代碼放在我們想放的地方,而不用擔(dān)心破壞響應(yīng)應(yīng)性。

作者:Michael Thiessen

譯者:小智 來源:vuemastery

原文:https://www.vuemastery.com/blog/coding-btter-composables-1-of-5?


文章名稱:Vue3,用組合編寫更好的代碼:AsyncWithoutAwait模式
轉(zhuǎn)載源于:http://www.dlmjj.cn/article/dhgcohd.html