Promise.all 比预期更早解决

2023-12-28

我正在使用 Promises 编写第一段代码,并得到了一些意想不到的结果。我有一些看起来像这样的代码(使用 jQuery):

$('.loading-spinner').show();
$('.elements').replaceWith(function() {
   // Blocking code to generate and return a replacement element
});
$('.newElements').blockingFunction();
$('.loading-spinner').hide();

为了防止页面在运行此代码时被阻止,我尝试使用 setTimeout 和 Promises 使其异步,如下所示:

$('.loading-spinner').show();
var promises = [];
var promises2 = [];
$('.elements').each(function(i, el){
    promises[i] = new Promise(function(resolve, reject) {
        setTimeout(function() {
            $(el).replaceWith(function() {
                // Code to generate and return a replacement element
            });
            resolve(true);
        }, 100);
    });
});
Promise.all(promises).then(function(values) {
    $('.newElements').each(function(i, el) {
        promises2[i] = new Promise(function(resolve, reject) {
            setTimeout(function() {
                $(el).blockingFunction();
                resolve(true);
            }, 100);
        });
    });
});
Promise.all(promises2).then(function(values) {
    $('.loading-spinner').hide();
});

我想要实现的是,一旦承诺promises已解决,承诺promises2被实例化。一旦这些问题得到解决,加载微调器就会被隐藏。

我得到的效果是,虽然页面没有被阻塞那么长时间,但一旦设置了所有 Promise,微调器就会消失,而不是等到它们得到解决。

我可以看到promises2直到一切都完成后,承诺才会得到解决promises已解决,所以我不明白为什么会发生这种情况。我想这要么是我没有正确理解 Promise,要么是没有低估使代码异步。


你正在呼唤Promise.all on promises2在填充它之前,事实上,当您调用它时,它包含一个空数组,因此它调用Promise.all在一个空数组上,因此它会立即解析,而无需等待中的承诺promises.


快速解决:

function delay(ms){ // quick promisified delay function
    return new Promise(function(r){ setTimeout(r,ms);});
}

var promises = $('.elements').map(function(i, el){
    return delay(100).then(function(){
        $(el).replaceWith(function() {
            // Code to generate and return a replacement element
        });
});
Promises.all(promises).then(function(els){
    var ps = $('.newElements').map(function(i, el) {
        return delay(100).then(function(){ 
            $(el).blockingFunction();
        });
    });
    return Promise.all(ps);
}).then(function(){
    $('.loading-spinner').hide();
});

但我们可以做得更好,没有理由解雇n超时n要素:

delay(100).then(function(){
    $(".elements").each(function(i,el){ 
        $(el).replaceWith(function(){ /* code to generate element */});
    });
}).
then(function(){ return delay(100); }).
then(function(){
    $('.newElements').each(function(i, el) { $(el).blockingFunction(); });
}).then(function(){
    $('.loading-spinner').hide();
}).catch(function(err){
   throw err;
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Promise.all 比预期更早解决 的相关文章

随机推荐

  • AngularJS - 将变量传递到“$routeProvider”

    试图找出一种 特定于角度 的方法来尝试实现这一目标 我有一个包含一些视图的页面 当用户单击锚点时 视图会发生变化 我工作得很好 我很好奇的是 当用户点击时 是否可以存储一个变量 比如内部 html 然后将其传递给 routeProvider
  • 为什么有时scrollTop/scrollLeft不可写?

    我正在使用 dhtmlx 甘特图 UI 组件 其中包含任务列表和图形图表 任务列表和图形图表包含在两个独立的 div 元素中 它们同步并行滚动 通过滚动图表区域 任务列表会自动滚动 从而使任务行位置与甘特线位置相匹配 检查组件源代码 我发现
  • Pytorch 卷积自动编码器

    如何构建卷积自动编码器的解码器部分 假设我有这个 input gt conv2d gt maxpool2d gt maxunpool2d gt convTranspose2d gt output CIFAR images shape 3 x
  • 在 Windows 中安装适用于 python 3 的 Swampy

    我是一个Python初学者 使用 Think Python 一书 我必须在其中安装模块名称Swampy 提供的说明和下载链接有一个tar gz http pypi python org pypi swampy 2 1 1文件 我用googl
  • 带时间盐的客户端 MD5 哈希

    我想在客户端的 JS 中使用高阶时间值 这将使所传递的哈希值的有效性短暂失效 如果他们检查 JS 并发现它使用了这个时间盐 那么如果他们知道盐是什么 那么破解 MD5 的工作会容易得多吗 Stephen The 盐不需要保密 https s
  • 在 python3 中迭代有限的 dict_values

    使用 py3 我试图简单地迭代dict values这是 python3 中的视图 而不是list 所以我不能这样做dict values limit 不再了 无法在 py3 中执行以下操作 In 1 large dict values l
  • Android 模拟器 4.2.2 未在锁定屏幕中显示添加小部件选项 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在较新的 Android 版本中 您
  • 使用应用内购买进行购买时是否可以添加额外数据

    这是一个场景 我们的应用程序上有多个老师 用户可以从老师那里购买 3 种不同的物品 价格为 20 美元 30 美元 40 美元 所以我在 google play console 中创建了 3 个产品 用户购买时 某些物品我如何知道他从哪位老
  • 如何从 Ada 源构建可从 C++ 代码调用的静态库?

    我需要使用一堆用 Ada 编写的代码构建一个静态库 可以从用 C C 编写的代码中调用这些代码 我通过互联网搜索并了解了一些知识gnatmake gnatbind and gnatlink 但仍然无法正确完成工作 另外 我读到有些工具依赖于
  • Redis 命令获取所有可用密钥?

    是否有一个 Redis 命令可以获取数据库中的所有键 我见过一些 python redis 库获取它们 但想知道是否可以通过 redis client 实现 尝试看看KEYS http redis io commands keys命令 KE
  • 引导面板无法正常工作

  • 在ggplot2中,如何更改选定面的边框?

    从 ggplot2 帮助页面获取图表 ggplot mtcars aes factor cyl geom bar facet grid vs 是否可以仅更改选定面板的边框 颜色和 或厚度 例如 我想更改分面变量 1 的分面的边框vs 我尝试
  • 在可移植库中使用 CallerMemberName 属性

    我有一个针对 Windows Phone 7 1 和 Windows 应用商店应用程序 用于 WinRT 的便携式库 它使用 net 4 5 框架 我想使用新的 CallerMemberName 属性在其中 然而 VS2012告诉我 这个属
  • c中printf中的多个赋值语句[重复]

    这个问题在这里已经有答案了 谁能帮我理解下面代码的输出 int main int a 35 printf d d d d d a a a 20 a a 39 return 0 output 20 19 19 39 19 了解如何在 c 中的
  • 谷歌的函数绘图仪

    如果您在 google com 上搜索数学方程 大多数情况下谷歌会自动为您绘制它 例如 您可以输入sin x x甚至是逗号分隔的列表 例如sin x x cos x x在同一个图表上绘制多个函数 我知道还有其他 Javascript 绘图库
  • Eclipse:Android 项目中 JDK 类的 java.lang.NoClassDefFoundError

    首先 我想提一下我读过manystackoverflow 帖子关于没有发现类定义错误 我也在many其他博客和网站 但人们提供的解决方案并没有解决这个问题 我在跑步Eclipse 64 位使用 ADT 插件版本 v21 0 1 543035
  • 使用“图表到系统托盘”最小化表单时出现问题,

    我有一个表单 通过挂接到 form resize 事件 将其最小化到系统托盘 一切都很顺利 直到我在表单中添加了图表 当图表出现在表单上时 我会得到以下异常 宽度必须大于 0px 突出显示的行是 this ShowInTaskbar fal
  • 关于线程安全和 JPA EntityManager

    假设我们有两个相互依赖的实体 并且每个实体都有 DAO Entity1 gt Entity2 Entity2 现在假设我们有两个线程从数据库中提取一些数据 Thread1 要求 Entity1Dao 获取一些已初始化依赖字段的对象 同时 T
  • StripeInvalidRequestError:您不能使用 `line_items.amount`、`line_items.currency`、`line_items.name`、`line_items.description` 或 `line_ite

    我正在构建 Amazon 克隆 当我尝试将 stripe 与克隆集成时 出现以下错误 有人可以帮帮我吗 我指的视频是这个 错误片段 错误 StripeInvalidRequestError 您无法使用line items amount li
  • Promise.all 比预期更早解决

    我正在使用 Promises 编写第一段代码 并得到了一些意想不到的结果 我有一些看起来像这样的代码 使用 jQuery loading spinner show elements replaceWith function Blocking