你怎么知道无限长的承诺链何时完全结束?

2024-04-27

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

// 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/ http://jsfiddle.net/jfriend00/4hfyahs3/

但是,这会构建一个可能永无止境的承诺链,因为变量p存储最后一个承诺的信息永远不会被清除。每一次新的行动都与之前的承诺挂钩。所以,我在想,为了良好的内存管理,我应该能够检测到何时没有更多内存.then()剩下的处理程序在当前值上运行p然后我可以重置值p,确保先前的 Promise 处理程序链可能在闭包中保存的任何对象都符合垃圾回收的条件。

所以,我想知道在给定的情况下我怎么知道.then()处理程序没有更多.then()在这个链中调用处理程序,因此,我可以这样做p = Promise.resolve()重置p并释放之前的承诺链,而不是不断地添加它。


有人告诉我,“良好”的承诺实现不会导致无限增长的承诺链中积累内存。但是,显然没有标准要求或描述这一点(除了良好的编程实践),并且我们有很多新手 Promise 实现,因此我尚未决定依赖这种良好行为是否明智。

我多年的编码经验表明,当实现是新的时,缺乏所有实现都以某种方式运行的事实,并且没有规范表明它们应该以这种方式运行,那么以“安全”的方式编写代码可能是明智的尽可能。事实上,仅仅围绕不确定的行为进行编码通常比测试所有相关的实现以了解它们的行为要少得多。

本着这种精神,这是我的代码的实现,在这方面似乎是“安全的”。它只是为每个保存全局最后一个承诺变量的本地副本.then()处理程序,当那个.then()处理程序运行,如果全局 Promise 变量仍然具有相同的值,那么我的代码没有将任何更多项目链接到它上面,所以这必须是当前的最后一个.then()处理程序。它似乎工作在这个jsFiddle http://jsfiddle.net/jfriend00/qtbxq0et/:

// 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;
    });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你怎么知道无限长的承诺链何时完全结束? 的相关文章

  • 我的用户脚本如何根据链接的文本获取链接?

    给定目标页面上的 HTML dd class ddTit a href http abc xxx com 54781 html target blank special text words a dd 我怎样才能根据 获取url特殊文字词
  • React Native 将样式设置为 State

    我想用backgroundColor of style1作为一种状态 并在函数中改变它change 我怎样才能访问style1 我的观点是调用该函数change从另一个函数 使按钮将其颜色更改为黄色 然后在一段时间后再次将其颜色更改为蓝色
  • 将数组中的所有值作为参数传递给函数

    我有一个值数组 a b c d 我需要将它们作为参数传递给函数 window myFunction a b c d 如果我可以将数组 对象传递到函数中 那么这会更容易 但这些函数是由其他人编写的或已经存在 我无法更改它们 它们需要作为单独的
  • 从字符串中删除货币符号并使用 Javascript 中的单行转换为数字

    我下面有一个字符串 它是以英镑为单位的价格 我想删除货币符号 然后将其转换为我可以用来与另一个值进行比较的数字 价格 例如 X gt Y 14 50 我之前已将字符串转换为用于货币的数字 var priceNum parseFloat pr
  • 了解执行模型和事件循环

    我读过很多关于JavaScript单线程执行模型 事件循环和事件队列的文章 但有一件事尚不清楚 我创建了一个小提琴来说明我的问题 http jsfiddle net yzpmf67f http jsfiddle net yzpmf67f
  • 表单未使用 AJAX 提交

    再次更新 如果有人关心的话 我之前发布的解决方案由于某种原因停止工作 我在 ajax 请求中包含了 beforeSend 并将验证表单的 js 部分粘贴到其中 现在就像一个魅力 form on submit function e e pre
  • jquery/javascript 处理后移至命名锚点

    在进行一些 jquery 处理后 如何将焦点移动到同一页面上的不同部分 名为锚点 函数 ABC 进行一些处理 然后 我需要将用户移动到同一页面上的某个部分 页面下方 您可以使用下面的代码将屏幕滚动到 div 只需更改选择器以匹配您要滚动到的
  • 通过单击字段启用非活动字段

    是否可以有一组非活动字段 如果单击其中一个字段 则某些字段将变为必填字段并运行某些代码段 举例来说 您显示了三个字段
  • JavaScript 中的常用数字

    在我的任务中 我必须编写一个程序来查找数组中最常见的数字以及它重复的次数 我写了一些东西 但只打印最大重复次数 所以我的问题是如何打印这个元素的值 最大数量 在我的例子中是 4 var array 13 4 1 1 4 2 3 4 4 1
  • Angular 2 最终版本路由器单元测试

    如何使用 karma 和 jasmine 对 Angular 2 0 0 版中的路由器进行单元测试 这是我的旧单元测试在版本 2 0 0 beta 14 中的样子 import it inject injectAsync beforeEac
  • 嵌套对象的 AJV 模式验证

    函数返回的对象看起来像这样 answer vehicle type 1 message Car model VW color red 答案 对象始终存在 其他字段基于 vehicle type E g 如果vehicle type 1 则有
  • 使用JS将图像的特定背景颜色设置为透明

    我正在使用以下代码来修改图像的透明度 然而 我想做的只是修改图像的背景颜色并将其 alpha 通道设置为 0 而不是整个图像 以下代码将整个图像的 Alpha 透明度设置为 0 var ctx this data getContext 2d
  • 在 NPM 上捆绑并发布客户端 Web 代码

    我制作了一个 JavaScript 文件 假设它的内容是这样的 let myCoolAlert str gt alert str in a different js file SO doesn t allow you to cross fi
  • 日期时间的自定义 JavaScriptConverter?

    我有一个对象 它有一个 DateTime 属性 我想通过 AJAX JSON 将该对象从 ashx 处理程序传递回网页 我不想使用第 3 方控件 当我这样做时 new JavaScriptSerializer Serialize DateT
  • 单击窗口后才检测到 keydown

    在我的 Web 应用程序中 我有一个用于打开菜单的键的事件侦听器 仅当我单击页面上的任意位置后 此功能才可以正常工作 我尝试将焦点添加到窗口加载 但这仍然不会让 keydown 函数运行 直到我单击页面上的某个位置之后 有谁知道这是否可能
  • 如何在变量名中使用变量

    所以我正在使用这样的 json 变量 opponentInvData item1 它包含项目 1 到 6 我需要动态访问不同的项目并将它们设置为空 itemNum 是我需要访问的特定项目 我正在尝试使用 eval 函数 var itemNu
  • 如何在 Javascript 中将字符串数组转换为特定的树结构

    我从后端获取文件路径列表 它代表文件夹结构 如下所示 paths path to file1 doc path to file2 doc foo bar doc 路径的长度是任意的 为了使用文件树组件 角度2树组件 https github
  • JavaScript 数组中的负索引是否会影响数组长度?

    在javascript中我定义了一个像这样的数组 var arr 1 2 3 我也可以做 arr 1 4 现在如果我这样做 arr undefined 我也失去了对值的引用arr 1 所以对我来说 从逻辑上来说 arr 1 也是arr 但是
  • 使用 Promise 语法编写同步代码有什么好处吗?

    有同步承诺这样的概念吗 使用 Promise 语法编写同步代码有什么好处吗 try foo bar a b bam catch e handleError e 可以写成类似的东西 但使用同步版本then foo then bar bind
  • 如何在odoo中重写js函数

    我想加载 shop checkout url 函数是 odoo define change info order website sale change info order function require use strict oe w

随机推荐

  • 触发变量中 python 字符串的 f 字符串解析

    这个问题来自于处理jupyter magics 但可以用更简单的方式表达 给定一个字符串s the key is d key 和一本字典d key val 我们要解析该字符串 旧的方法是 format 这会引发错误 它不处理字典键 the
  • 如何使用RedirectToAction重定向到页面中的某个位置?

    我在一个项目中使用 MVC4 C 和 Visual Studio Ultimate 2013 我在提交表单后将用户重定向到索引页面 但是 该网页有 2 个选项卡 我想将用户重定向到第二个选项卡 而不是第一个选项卡 我有一个名为Materia
  • Angular2:如何获取自定义响应标头(CORS问题)

    为什么我无法从响应中访问 Angular2 中的所有标头 我有一个无法修改的旧版 Web 服务 它将一些重要信息发送回客户端响应标头 别问我为什么 这是废话 我的代码是这样的 subscribe r Response gt var cust
  • 类型双关:省略放置 new 和析构函数

    已经有很多关于严格别名规则和类型双关的帖子 但我找不到我可以理解的关于对象数组的解释 我的目标是拥有一个内存池非模板类 用于存储对象数组 基本上我只需要在访问时知道实际类型 它可以被视为一个非模板向量 其迭代器将是模板 我想到的设计提出了几
  • 从 Scala/Spark 写入 SQL Server 日期时间数据类型

    我正在尝试使用类似的方法从 databricks 笔记本批量插入 SQL Server 表 批量复制到 Azure SQL 数据库或 SQL Server https docs databricks com spark latest dat
  • Prism 6 区域管理器 RequestNavigate 无法导航某些区域

    我有一个用户控件 其中定义了多个用于注入视图的 Prism 区域 我决定使用 Prism 视图导航来处理切换 我的 SelectedMenuContentRegion 基于用户操作 如下所示 我遇到了问题 我确信问题出在我的使用上 但我无法
  • 更改WinForm中标题栏的颜色

    是否可以在 C 中更改 WinForm 标题栏的颜色 Form1 X lt I want to change the color of this 我解决了这个问题 这是代码 DllImport User32 dll CharSet Char
  • 使用 Javascript/CSS 设置 IE“光学变焦”功能

    我维护的网站的设计相当严格 使用像素来表示字体大小 尺寸 绝对定位等 现在有一个功能请求 要求添加用户调整字体大小的功能 虽然我知道如果不使用相对尺寸从头开始重新设计网站 这是不可能的 但我发现该网站与 IE7 IE8 缩放功能 Ctrl
  • 如何将 HTML 代码转换为 JSON 对象?

    我正在构建一个 Angular 7 应用程序 在此应用程序中 我让用户编辑 HTML 然后我希望将其转换为 JSON 以便以有意义的方式存储它 简而言之 我想获取任何 HTML 代码并将其处理为 JSON 对象 我怎样才能做到这一点 我会将
  • WPF/Silverlight 中的动画资源?

    我正在寻找一些好的资源来增强 WPF Silverlight 中使用的动画 故事板概念 有什么指点吗 发布的一个链接是 WPF 特定的 对于 Silverlight 这里还有一些其他资源 MSDN 动画概述 http msdn micros
  • UnsatisfiedLinkError:dlopen 失败:无法找到引用的符号“__aeabi_memcpy4”

    我刚刚从 NDK 12 x 更新到 13 x 现在遇到以下崩溃 Caused by java lang UnsatisfiedLinkError dlopen failed cannot locate symbol aeabi memcpy
  • android dexclassloader 获取所有类的列表

    我在我的 Android 应用程序中使用来自 asset 或 sdcard 的外部 jar 为此 我使用 DexClassLoader DexClassLoader cl new DexClassLoader dexInternalStor
  • 使用 Android SDK 随机访问文件 > 2GB

    谁能告诉我如何使用 android SDK 随机访问超过 2GB 的文件 我试图寻找 gt 2147483647 的位置并得到异常 值对于定义的数据类型来说太大 这很奇怪 因为查找命令的参数是 long 类型 详细内容请参见代码示例 Ran
  • Python 中是否有 Mechanize 的替代方案? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用Python 3 6 而我必须填写表格 不幸的是 mechanize 不适用于 Python 3 作为机械化的替代方案 您有何建
  • 水平滚动视图无法正常工作 swiftUI

    我试图显示一些水平视图 但它不起作用 下面是我正在使用的代码 State var userDataList UserModel var body some View VStack spacing 10 VStack prefView pad
  • iOS App 中 AVAudioPlayer 和 MPMusicPlayerController 的独立音量控制。

    在我的应用程序中 我使用 AVAudioPlayer 播放下载的音频 同时使用 MPMusicPlayerController 播放用户 iPod 音乐库中的音频 我需要能够调整 AVAudioPlayer 实例的音量 使其声音更大 比来自
  • 为什么 GCC 9.1.0 有时会抱怨 strncpy() 的这种使用?

    这是一个 40 行 MCVE 最小 完整 可验证的示例 https stackoverflow com help mcve 或者接近最小的东西 从最初包含 32 个标头的 1675 行源文件中删减 其中大多数包含多个其他标头 编译它gcc
  • gcc 如何知道内联汇编中使用的寄存器大小?

    我有内联汇编代码 define read msr index buf asm volatile rdmsr d buf 1 a buf 0 c index 使用该宏的代码 u32 buf 2 read msr 0x173 buf 我发现反汇
  • 如何在活动脚手架导轨 3 中添加新链接

    我需要在我的出租车列表页面中添加一个新链接 地图 我使用的是 active scaffold 和 Rails 3 2 1 我当前的页面如下所示 我需要在每条记录中显示类似于编辑 删除 显示的链接 地图 在我的数据库中 我有字段名称 纬度 经
  • 你怎么知道无限长的承诺链何时完全结束?

    我试图使用 Promise 强制序列化一系列 Ajax 调用 用户每次按下按钮时都会进行这些 Ajax 调用 我可以成功地序列化操作 如下所示 sample async function real world this is an Ajax