首頁 > web前端 > js教程 > JavaScript規劃任務後台運行的方法_javascript技巧

JavaScript規劃任務後台運行的方法_javascript技巧

WBOY
發布: 2016-05-16 15:24:48
原創
1788 人瀏覽過

即使忘了 JavaScript 的一切知識,也不會忘記:它是阻塞的。

想像一下,你的瀏覽器裡住著一個魔法小精靈,負責瀏覽器的正常運作。不論渲染 HTML,回應選單指令,螢幕渲染,處理滑鼠點擊,或執行 JavaScript 函數,所有事情都歸一個小精靈處理。它哪忙得過來,一次只能處理一件事情。如果同時丟給它一堆任務,它會列出一個長長的待辦列表,按順序完成它們。

人們常常希望初始化元件和事件處理的 JavaScript 可以盡快執行。可是,有些較不重要的後台任務不會直接影響使用者體驗,例如:

記錄統計

發送資料到社群網路(或新增『分享'按鈕)

預先載入內容

預處理或預先渲染 HTML

他們對時序要求不嚴格,但是為了讓頁面仍然回應,直到使用者捲動頁面或與內容互動時才執行。

選擇之一是 Web Workers ,它可以在獨立的執行緒同時執行程式碼。用於預先載入和預處理再好不過,但是你沒有權限直接存取或更新 DOM。你可以在自己的程式碼中避開這一點,但是無法保證第三方腳本例如 Google Analytics 永遠不需要這個。

另一個選擇是setTimeout,例如setTimeout(doSomething, 1);。一旦其它的立即執行任務執行完畢,瀏覽器將執行doSomething()函數。實際上,它被放到了待辦清單的底部。不幸的是,函數將被調用,而不顧處理需求。

#requestIdleCallback

requestIdleCallback 是新API,當瀏覽器稍作喘息的時候,用來執行不太重要的後台排程任務。 難免讓人想起 requestAnimationFrame ,在下次重繪之前,執行函數更新動畫。 想了解更多戳這裡: 使用 requestAnimationFrame 做簡單的動畫 。

requestIdleCallback特性監控:

1

2

3

4

5

6

7

8

9

10

if ('requestIdleCallback' in window) {

 // requestIdleCallback supported

 requestIdleCallback(backgroundTask);

}

else {

 // no support - do something else

 setTimeout(backgroundTask1, 1);

 setTimeout(backgroundTask2, 1);

 setTimeout(backgroundTask3, 1);

}

登入後複製

也可以指定配置參數對象,例如 timeout,

1

requestIdleCallback(backgroundTask, { timeout: 3000; });

登入後複製

確保函數在3秒內調用,不管瀏覽器是否空閒。

deadline物件傳入下列參數時,requestIdleCallback只執行一次回呼:

didTimeout—— 如果可選的 timeout 觸發,則設定為 true
timeRemaining()—— 函數傳回執行任務剩餘的毫秒數
timeRemaining()最多分配50ms用於任務的執行,超過這個限制,也不會停止任務,但是,最好重新呼叫requestIdleCallback安排進一步的處理。

我們來建立一個簡單的例子,讓幾個任務依序執行。任務的函數引用儲存在數組中:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

//待执行的函数数组

var task = [

  background1,

  background2,

  background3

];

if ('requestIdleCallback' in window) {

 //支持 requestIdleCallback

 requestIdleCallback(backgroundTask);

}

else {

 //不支持 —— 立刻执行所有任务

 while (task.length) {

  setTimeout(task.shift(), 1);

 }

}

//requestIdleCallback 回调函数

function backgroundTask(deadline) {

 //如果存在,执行下一个任务

 while (deadline.timeRemaining() > 0 && task.length > 0) {

  task.shift()();

 }

 //需要的话,安排进一步任务

 if (task.length > 0) {

  requestIdleCallback(backgroundTask);

 }

}

登入後複製

#一次 requestIdleCallback 之間不應該做什麼?

Paul Lewis 在 他的文章 中提到,一次 requestIdleCallback 執行的任務應該切成小塊。它不適用於不可預測時間的情況(例如操作 DOM,使用 requestAnimationFrame 回呼會更好)。 resolving(或 rejecting)Promises 時也要謹慎,即使沒有更多的剩餘時間,空閒回調完成之後,回呼函數也會立即執行。

#requestIdleCallback 瀏覽器支援狀況

requestIdleCallback是試驗性特性,規格仍不穩定,碰到 API 變更時不足為奇。 Chrome 47 已支援… 2015年結束前應該可用了。 Opera 應該會跟上。 Microsoft 和 Mozilla 都在考慮 API 是否應該支援 Promises 。 Apple 像往常一樣不鳥。

Paul Lewis(上文提到的)寫了一個簡單的 requestIdleCallback shim ,它可以模擬瀏覽器的空閒監測行為,但不是一個 polyfill( shim 和 polyfill 的區別 )。

requestIdleCallback shim程式碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

/*!

 * Copyright Google Inc. All rights reserved.

 *

 * Licensed under the Apache License, Version . (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 * http://www.apache.org/licenses/LICENSE-.

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

 * or implied. See the License for the specific language governing

 * permissions and limitations under the License.

 */

/*

 * @see https://developers.google.com/web/updates///using-requestidlecallback

 */

window.requestIdleCallback = window.requestIdleCallback ||

 function (cb) {

  var start = Date.now();

  return setTimeout(function () {

   cb({

    didTimeout: false,

    timeRemaining: function () {

     return Math.max(, - (Date.now() - start));

    }

   });

  }, );

 }

window.cancelIdleCallback = window.cancelIdleCallback ||

 function (id) {

  clearTimeout(id);

 }

登入後複製

ps: How to run a scheduled task

1. Run GPEDIT.MSC

2. Select computer configuration

--- Windows Settings
                                                                 Security settings
​​​​—Local Strategy
​​​​​—-User Rights Assignment
Double-click Access this computer from the network on the right
Add the required usernames to the list.

3. --- Security settings

---Safe choice
Turn on Allow server operators to schedule tasks

4.-----Local strategy

--- Log in as a batch job
Add the required usernames to the list.

5.-----Local strategy

--- Allow computers and users to be trusted for delegation
Add the required usernames to the list.
It is best to be the administrator user.

If the task plan cannot be started, prompt code: 0X80041315

Solution: There are two possibilities. One is that the "Task Scheduler" service in the system is not started. You can type "services.msc" during operation to check whether the "Task Scheduler" service is set to "Already set". Disabled", if so, just double-click it to change the startup type to "Automatic", reset a scheduled task and it can be executed.

If your current account is set to automatically log in, and its login password is empty, it may also cause the task plan to not be executed on time. In XP Professional Edition, you need to run "gpedit.msc" to edit the group policy: expand "Computer" Configuration→Windows Settings→Security Settings→Local Computer Policy→Security Options"; double-click the "Accounts: Local accounts with blank passwords only allow console login" item on the right, and select "Disabled" in the pop-up dialog box.

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板