簡體   English   中英

延遲jquery的計時問題

[英]timing issues with jquery deferred

這個問題是精心提煉的非異步函數版本, 作為jQuery Deferred執行

我們有2個jsfiddles:

  1. http://jsfiddle.net/XSDVX/1/ - 盡管調用了notify()函數,但不會觸發progress事件。

  2. http://jsfiddle.net/UXSbw/1/ - 這里按預期觸發進度事件。

唯一的區別是一行代碼:

setTimeout(dfd.resolve,1);

dfd.resolve();

問題是:

  1. 當我們延遲解決時,如何捕獲在此回調返回之前調用的.notify? 想一想。 .then獲取從它的第一個參數返回的延遲對象,並從中創建一個新的延遲對象,綁定到它完成的進度和失敗事件。 如果在返回deferred之前調用了notify,那么即使使用setTimeout,如何捕獲它呢? (感謝https://stackoverflow.com/users/400654/kevin-b詢問此問題)

  2. 我可以擺脫setTimeout()並仍然有進程回調被解雇?

做了一個大的重構,這是一個最后的工作示例,進行監控。

現在重要的部分。

  • 在調用resolve之后,JQuery deferreds不執行任何進度回調( 有一個例外 )。 在您的示例中(沒有setTimeout),延遲會立即解決,無法運行進度。
  • 我們觸發最終延期的enything 之前 ,做所有回調的鈎子,尤其是進度回調。 這是通過我們填充它的觸發器之后將最終的Deferred(現在的beacon)傳遞給執行函數來實現的。
  • 我重構了API,因此要執行的func是延遲不可知的。
  • 這個解決方案,在memo.then函數內部使用一個本地的閉包 (to reduce iterator function)Deferred,以便繼續執行鏈。

編輯:我忘記了你的第一個問題。 這種行為是通過閉包 (“x”函數中的dfd變量)來實現的。

函數“x”立即返回(在觸發現在可以處理的通知事件之后,因為已經創建了執行鏈的所有延遲,並且已經掛起了“executePromiseQueueSync”的完成,失敗,進度掛鈎)。

此外,setTimeout的函數“關閉”閉包中的dfd,因此它可以訪問變量,盡管“x”已經返回。 “then”調用通過創建鏈接到第一個延遲的下一個延遲來繼續。

在JS VM產生之后(它沒有其他事情可做),setTimeout觸發它的相關函數,(通過閉包)可以訪問“已關閉”的dfd變量。 延期已解決,鏈可以繼續。

EDIT2: 這是一個重構版本 ,它增加了對長執行,延遲支持函數的支持,它們通知調用者他們的進度。

EDIT3:這是另一個版本 ,沒有下划線綁定和jq-ui進度條示例。

順便說一句,這對復雜的應用程序初始化例程來說非常好。

來源(第一版)

function executePromiseQueueSync(queue, beacon){
    var seed = $.Deferred(),
        le = queue.length,
        last;
    beacon.notify(0);
    last = _.reduce(queue, function(memo, ent, ind){
       var df = $.Deferred();
        df.then(function(){
            console.log("DBG proggie");
            beacon.notify((ind+1)/le*100);
        });
        console.log("DBG hook funk "+ind);
        memo.then(function(){
          console.log("DBG exec func "+ind);
          ent.funct.apply(null, ent.argmnt);
          df.resolve();
        });

        return df.promise();
    }, seed.promise());
    last.then(function(){
        beacon.resolve(100)
    });
    seed.resolve(); // trigger

    return beacon.promise();
}

function x(){
    // do stuff
    console.log("blah");
}

var promisesQueue = [],
     beacon = $.Deferred(); 

promisesQueue.push({funct: x, argmnt:[]});
promisesQueue.push({funct: x, argmnt:[]});
promisesQueue.push({funct: x, argmnt:[]});

function monTheProg(pct) 
{
    console.log('progress '+pct);
}

// first hook, then exec
beacon.then(function(){
        console.log('success');
    }, function(){
        console.log('failure');
    }, monTheProg);

// do the dance
executePromiseQueueSync(promisesQueue, beacon)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM