jquery的时序问题推迟(timing issues with jquery deferred)

2019-08-19 22:02发布

这个问题是精心蒸馏版本的jQuery的递延不执行异步函数 。

我们有2个jsfiddles:

  1. http://jsfiddle.net/XSDVX/1/ -这里的进度事件不会触发,尽管调用通知()函数。

  2. http://jsfiddle.net/UXSbw/1/ -在这里按预期进度事件。

唯一的区别是一行代码:

setTimeout(dfd.resolve,1);

dfd.resolve();

问题是:

  1. 。那么如何追赶,当我们拖延解决被这个回调返回之前叫.notify? 想想吧。 。然后将取得在返回从它的第一个参数的递延对象,并从它创建一个新的Deferred对象,结合它的完成进度和失败事件。 如果通知调用之前延期归还,怎么连。然后用setTimeout的追赶呢? (感谢https://stackoverflow.com/users/400654/kevin-b提出这项)

  2. 我可以摆脱setTimeout()仍然有进步的回调解雇?

Answer 1:

做了一个大重构,这里是一个最终的工作示例,以监测进展情况。

现在的重要组成部分。

  • JQuery的deferreds不执行任何进展回调,决心一直被称为(后有一个例外 )。 在您的例子(没有的setTimeout),递延立即解决,没有机会跑的进展。
  • 是否所有回调的挂钩,尤其是那些进步,我们触发enything最终延期 。 这是通过最后的递延(现在灯塔)的执行功能, 经过我们填充它的触发器来实现的。
  • 我重构的API,因此要执行的func被推迟无关。
  • 该解决方案,使用一个封闭件递延本地的(到减少迭代器功能)时,memo.then函数内,以便继续执行链。

编辑:我忘了你的第一个问题。 此行为通过的手段实现封闭 (在“x”函数的DFD变量)。

功能的“x”立即返回(触发通知它现在可被处理,作为执行链的所有Deferreds已创建的事件后,将完成的,失败,进步“executePromiseQueueSync”的挂钩已经被钩住)。

另外,setTimeout的功能“关闭”在封闭的DFD,所以尽管该“X”又回到它可以访问的变量。 该“然后”呼叫继续创造下一个递延链接到第一个。

在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)


文章来源: timing issues with jquery deferred