您怎么知道无限长的承诺链何时完全完成? [英] How do you know when an indefinitely long promise chain has completely finished?

查看:63
本文介绍了您怎么知道无限长的承诺链何时完全完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Promise强制序列化一系列Ajax调用.每次用户按下按钮时,都会进行一次这些Ajax调用.我可以成功地序列化这样的操作:

I was trying to use promises to force serialization of a series of Ajax calls. These Ajax calls are made one for each time a user presses a button. I can successfully serialize the operations like this:

// sample async function
// real-world this is an Ajax call
function delay(val) {
    log("start: ", val);
    return new Promise(function(resolve)  {
        setTimeout(function() {
            log("end: ", val); 
            resolve();
        }, 500);
    });
}

// initialize p to a resolved promise
var p = Promise.resolve();
var v = 1;

// each click adds a new task to 
// the serially executed queue
$("#run").click(function() {
    // How to detect here that there are no other unresolved .then()
    // handlers on the current value of p?
    p = p.then(function() {
        return delay(v++);
    });
});

正在运行的演示: http://jsfiddle.net/jfriend00/4hfyahs3/

但是,由于从未清除存储最后一个承诺的变量 p ,因此这会建立一个可能永无止境的承诺链.每个新操作都只是束缚于先前的承诺.因此,我在想,为了实现良好的内存管理,我应该能够检测到何时不再有 .then()处理程序可以在 p 的当前值上运行然后我可以重置 p 的值,确保先前的promise处理程序链可能在闭包中保存的所有对象都可以进行垃圾回收.

But, this builds a potentially never ending promise chain since the variable p that stores the last promise is never cleared. Every new operation just chains onto the prior promise. So, I was thinking that for good memory management, I should be able to detect when there are no more .then() handlers left to run on the current value of p and I can then reset the value of p, making sure that any objects that the previous chain of promise handlers might have held in closures will be eligible for garbage collection.

所以,我想知道如何在给定的 .then()处理程序中知道在此链中不再需要调用 .then()处理程序因此,我可以执行 p = Promise.resolve()来重置 p 并释放先前的Promise链,而不仅仅是不断添加它.

So, I was wondering how I would know in a given .then() handler that there are no more .then() handlers to be called in this chain and thus, I can just do p = Promise.resolve() to reset p and release the previous promise chain rather than just continually adding onto it.

推荐答案

有人告诉我,好的" promise实现不会导致无限期增长的promise链中的内存累积.但是,显然没有任何标准要求或描述此标准(除了良好的编程习惯),而且我们还有许多新手Promise实现,因此我尚未决定依靠这种良好行为是否明智.

I'm being told that a "good" promise implementation would not cause accumulating memory from an indefinitely growing promise chain. But, there is apparently no standard that requires or describes this (other than good programming practices) and we have lots of newbie Promise implementations out there so I have not yet decided if it's wise to rely on this good behavior.

我多年的编码经验表明,当实现是新的时,便缺乏所有实现都以某种方式运行的事实,并且没有说明它们应以这种方式运行的规范,因此以安全"的方式编写代码可能是明智的.一种可能的方式.实际上,仅对不确定行为进行编码通常要比对所有相关实现进行测试以了解其行为方式要少.

My years of coding experience suggest that when implementations are new, facts are lacking that all implementations behave a certain way and there's no specification that says they should behave that way, then it might be wise to write your code in as "safe" a way as possible. In fact, it's often less work to just code around an uncertain behavior than it is to go test all relevant implementations to find out how they behave.

从这个角度来看,这是我的代码的实现,在这方面似乎是安全的".它只是为每个 .then()处理程序保存了全局最后一个promise变量的本地副本,并且当该 .then()处理程序运行时,如果全局promise变量仍然具有相同的值,则我的代码没有在其上链接任何其他项目,因此它必须是当前最后一个 .then()处理程序.它似乎可以在此jsFiddle

In that vein, here's an implementation of my code that seems to be "safe" in this regard. It just saves a local copy of the global last promise variable for each .then() handler and when that .then() handler runs, if the global promise variable still has the same value, then my code has not chained any more items onto it so this must be the currently last .then() handler. It seems to work in this jsFiddle:

// sample async function
// real-world this is an Ajax call
function delay(val) {
    log("start: ", val);
    return new Promise(function(resolve)  {
        setTimeout(function() {
            log("end: ", val); 
            resolve();
        }, 500);
    });
}

// initialize p to a resolved promise
var p = Promise.resolve();
var v = 1;

// each click adds a new task to 
// the serially executed queue
$("#run").click(function() {
    var origP = p = p.then(function() {
        return delay(v++);
    }).then(function() {
        if (p === origP) {
            // no more are chained by my code
            log("no more chained - resetting promise head");
            // set fresh promise head so no chance of GC leaks
            // on prior promises
            p = Promise.resolve();
            v = 1;
        }
        // clear promise reference in case this closure is leaked
        origP = null;
    }, function() {
        origP = null;
    });
});

这篇关于您怎么知道无限长的承诺链何时完全完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆