11

我很驚訝,我無法找到明確的答案。因此,在jQuery中,你可以這樣做:jQuery如何具有異步功能?

$(someElements).fadeOut(1000); 
$(someElements).remove(); 

其中,將開始淡出動畫,但它完成在持續1秒執行前,該元素從DOM中移除。但是這怎麼可能?我一直在閱讀JavaScript是單線程的(另請參閱:Is JavaScript guaranteed to be single-threaded?)。我知道我可以做兩種:

$(someElements).fadeOut(1000).promise().done(function() { 
    $(someElements).remove(); 
}); 

甚至更​​好:

$(someElements).fadeOut(1000, function() { 
    $(this).remove(); 
}); 

什麼我不明白是怎麼的JavaScript運行在一個「單線程」但我能夠使用這些jQuery的函數異步執行,並且可以同時在不同的地方看到DOM變化。它是如何工作的? 這個問題不是:「我如何解決這個問題」。

+2

簡短的回答:CSS動畫或定時器。 – 2012-03-22 23:14:27

+0

我認爲是因爲jQuery使用動畫隊列,它在文檔中的某處.. – gpasci 2012-03-22 23:14:55

回答

5

jQuery動畫(以及幾乎所有基於JavaScript的動畫)都使用計時器來運行它們的動畫。對.fadeOut()的調用只是啓動動畫,並且直到稍後一系列定時器操作完成時纔會完成。

這仍然是單線程的。 .fadeOut()做動畫的第一步,它爲下一步設置一個計時器,然後您的javascript的其餘部分(包括.remove())運行直到完成。當那個JavaScript線程完成並且計時器已經過去的時間時,計時器會觸發並且動畫的下一步發生。最後,當動畫的所有步驟完成後,jQuery將調用動畫的完成函數。這是一個回調,允許您在動畫完成時執行某些操作。

那你是怎麼解決這個問題:

$(someElements).fadeOut(1000, function() { 
    $(this).remove(); 
}); 

您使用動畫完成的功能,只有當動畫完成刪除該項目。

+0

如果你想異步執行,你可能會考慮一個Web工作者或者如果你正在進行緊張的數據處理,可以使用(當前)實驗性的River Trail OpenCL橋接器。 – FlavorScape 2012-03-22 23:26:20

+0

我其實更喜歡JSTween,因爲它可以處理任何屬性。 – FlavorScape 2012-03-22 23:28:12

+1

@FlavorScape - Web工作人員無法與DOM進行交互,因此他們對動畫幫助不大。 – jfriend00 2012-03-22 23:43:58

1

在jQuery中有一個setInterval處理程序,它對所有註冊的動畫屬性執行轉換。如果你從AS3來了,把它作爲一個enterFrame事件處理程序,或像在OpenGL一個Draw方法

+0

我認爲在jQuery的最新版本中,它可能會使用requestAnimationFrame處理程序(由瀏覽器調度的事件)作爲更新/繪製函數 – FlavorScape 2012-03-22 23:18:36

+0

requestAnimationFrame has進出jQuery。它已經有一段時間了,然後因爲一些問題而被拔出。目前我沒有在1.7版本中看到它有源代碼可用。 – jfriend00 2012-03-22 23:21:12

+0

@ jfriend00你是正確的http://stackoverflow.com/questions/7999680/why-doesnt-jquery-use-requestanimationframe – FlavorScape 2012-03-22 23:27:23

0

您CA使用delay()等待一定的時間,或使用一個回調動畫時,fadeOutanimate改變。 jQuery使用setTimeout來設置動畫和隊列。

0

與20年前的操作系統完成多任務的方式大致相同。沒有線程,只有一些需要注意的事情和一個會根據列表關注事物的控制器。

單線程只是遍歷列表遍歷服務所有需要服務的東西。這裏唯一的區別是有些事情有關聯的等待期。他們在列表中,但被標記爲在一段時間後才能服務。本質上這是一個非常基本的調度器實現。計算機上的內核做同樣的事情。你的CPU只能同時執行幾個程序,即使這樣,也只是有點。操作系統內核必須以毫秒爲單位決定誰在毫秒級獲得關注(請參閱jiffies)。 Javascript的「內核」或者運行時間可以做同樣的事情,但基本上就像在只有一個內核的CPU上運行一樣。

這並不是談論中斷隊列等CPU可以應付的事情,我不確定Javascript有沒有類似的東西,但在簡單的層面上,我認爲這是一個公平的表示。

0

單線程與異步編程無關。 http://social.msdn.microsoft.com/Forums/uk/csharplanguage/thread/3de8670c-49ca-400f-a1dc-ce3a3619357d

如果你只有一個線程可以執行指令,它將不會/總是/正在執行。在那些空白的地方,這是更多工作的機會。異步編程只是將工作分解成能夠重新進入的塊,並且線程跳轉到需要的地方。 (概念解釋)

在這種情況下,您的問題可能更適合:爲什麼這不是阻止呼叫?在這種情況下,答案很明顯,就是將UI動畫與數據調用分開。整個JS環境不應該阻塞1秒,同時採取小片動畫元素,它可能會檢索或轉換數據,排隊等動畫的其他元素,等等。