2017-08-03 35 views
8

我有兩個async函數。他們兩個都在等待兩個3秒的函數調用。但第二個比第一個快。我認爲更快的是並行運行和其他串行運行。我的假設是否正確?如果是的話,爲什麼這兩個功能在邏輯上看起來是一樣的?如何異步/等待串行和並行工作?

function sleep() { 
    return new Promise(resolve => { 
    setTimeout(resolve, 3000); 
    }); 
} 

async function serial() { 
    await sleep(); 
    await sleep(); 
} 

async function parallel() { 
    var a = sleep(); 
    var b = sleep(); 
    await a; 
    await b; 
} 

serial().then(() => { 
    console.log("6 seconds over"); 
}); 

parallel().then(() => { 
    console.log("3 seconds over"); 
}); 
+0

你爲什麼認爲'setTimeout'是異步的?除了函數聲明外,代碼中沒有任何異步。 – Mjh

+3

@Mjh Errm,'setTimeout'就是非同尋常的異步......而且OP的代碼中的其他所有東西都是異步的...... – Frxstrem

+2

@Frxstrem除了'setTimeout'根本不是異步的。這是一個同步函數,它告訴事件循環以後再執行一個函數。這是*機制*​​,在這段代碼中絕對沒有異步。哪兩個運動部件以不同的速度在不同的執行環境中運動?零。因此,這個代碼根本不是異步的。 – Mjh

回答

4

Frxstream已經有an excellent answer。爲此,並提供一些觀點:

首先要承認的是Promise被創建爲「熱門」 - 也就是說,當您有承諾對象時,它已經「正在進行」。

第二個重要的概念是,await就像是一個「異步等待」 - 也就是說,它暫停執行該功能,直到該承諾完成。

因此,serial函數調用sleep,得到一個承諾,然後(異步)等待該承諾完成。在承諾完成3秒後,serial再次調用sleep,得到承諾,然後(異步)等待承諾完成。 3秒後完成承諾後,serial完成。

parallel函數調用sleep和存儲其承諾在a,然後調用sleep和存儲其承諾在b,然後(異步)等待a完成。在a 3秒後完成後,parallel(異步)等待b完成。在b立即完成後,parallel完成。

6

它更清晰,如果你寫你的serial功能是這樣的:

async function serial() { 
    var a = sleep(); // 
    await a;   // await sleep(); 

    var b = sleep(); // 
    await b;   // await sleep(); 
} 

async function parallel() { 
    var a = sleep(); 
    var b = sleep(); 
    await a; 
    await b; 
} 

在這裏,你可以清楚地看到,在serial功能,第二sleep()只在第一次sleep()完成後調用,而在parallel中,它在第一次完成之前立即被調用,然後等待兩者完成。所以雖然他們可能看起來功能相同,他們是微妙的不同。

3

因爲sleep()功能是同步的功能,它只是返回一個異步的承諾,例如:

function sleep (time) { 
    return new Promise((resolve) => setTimeout(resolve, time)); 
} 

parallel(),兩個sleep()同步初始化許諾實現,他們等待被同時解決,這將大約3s。

然而,在serial(),兩個await sleep()意味着第二sleep()承諾必須等待第一sleep()得到解決,所以這將是約6秒。