当前位置: 首页 > 知识库问答 >
问题:

等待所有嵌套promise完成,但仍对每个单独的解决方案作出反应

江丰羽
2023-03-14

假设newservice.getNews()返回一个promise,该promise应解析为某个服务返回的随机新闻条目,而translateService.translate()返回一个promise,该promise应解析为传递文本的翻译。

var newsPromises = [];
var translatePromises = [];
for (var i = 0; i < 5; i++) {
    var p1 = this.newsService.getNews();
    newsPromises.push(p1);

    p1.then(function (data) {
        var p2 = this.translateService.translate(data);
        translatePromises.push(p2);
        p2.then(function (translatedData) {
            addNews(`${data} (${translatedData})`);

        }, function (fail) {
            console.log(fail.message);
        });

    }, function (fail) {
        console.log(fail.message);
    });
}

现在,页面最初显示了一个加载微调器,我希望在所有promise(包括嵌套的翻译promise)完成(成功或失败)后隐藏该微调器:

   Promise.all(newsPromises)
        .then(function (results) {
            Promise.all(translatePromises).then(function (results) {
                    removeLoading();
                },
                function (err) {
                    removeLoading();
                }
            );

        }, function (err) {
            Promise.all(translatePromises).then(function (results) {
                    removeLoading();
                },
                function (err) {
                    removeLoading();
                }
            );
        });

这段代码a)不能正常工作,因为加载微调器有时会在promise解决之前消失,b)非常复杂。

如何正确地做到这一点?(配香草JS/ES6)

共有2个答案

昝卓
2023-03-14

在这种情况下,我创建全局计数器loadersCount=0

每次调用this.newservice.getNews()调用函数loaderStart()

每次调用addNews()console.log(fail.message)callloaderStop()

function loaderStart () {
  if (loadersCount === 0) {
    addLoading();
  }
  loadersCount++;
}

function loaderStop () {
  if (loadersCount === 1) {
    removeLoading();
  }
  loadersCount--;
}
卜勇
2023-03-14

请记住,promise链是管道,每个处理程序可以在结果通过处理程序时转换链的结果。见评论:

// We only need one array of promises
const promises = [];
// Build the array
for (let i = 0; i < 5; i++) {
    // Add this promise to the array
    promises.push(
        // Get the news...
        this.newsService.getNews().then(
            // ...and translate it...
            data => this.translateService.translate(data)
                .then(translatedData => {
                    // ...and show it as soon as it's available
                    addNews(`${data} (${translatedData})`);
                    // Note that here we're converting the resolution value to
                    // `undefined`, but nothing uses it so...
                    // If you want something to be able to use it,
                    // return `translatedData` (or `data` or...)
                })
        )
        .catch(fail => {
            console.log(fail.message);
            // WARNING: Here you're converting rejection to resolution with `undefined`
        })
    );
}
// Wait until all that is done before removing the loading indicator
Promise.all(promises).then(removeLoading);

请注意,我们不需要在promise上添加捕获的唯一原因。所有promise都是因为您忽略了(记录除外)发生的错误,因此我们知道promise永远不会拒绝。

还要注意的是,上面假设removeLoading不关注它收到的参数,并且它不会返回可能拒绝的promise。如果它确实关心参数,并且不带参数调用它很重要,请将promise。所有位更改为:

Promise.all(promises).then(() => removeLoading());

如果它返回可能拒绝的promise,您还需要一个catch处理程序。

 类似资料:
  • 我有一个复杂的对象图,我建立在一个Ember控制器。 所以,为了安排这一切,我基本上是想 创建conatainer, 然后,创建细节,其中可能有许多 然后,创建项目,其中会有尽可能多的细节 等待一切promise解决 启动一个自定义的Rest动作来“激活”容器,一旦它有了所有的东西。 代码看起来像这样(咖啡),简化了但我认为要点就在那里 当所有的promise都解决了,一切都是我想要的,然而,al

  • 所以我有一个情况,我有多个未知长度的promise链。我希望在处理完所有链后运行一些操作。这可能吗?这里有一个例子: 在本例中,我为promise一、promise二和promise三设置了一个,这些promise将在某个随机时间得到解决。然后,我在第一和第三段的末尾加上promise。我希望在解析所有链后解析。以下是我运行此代码时的输出: 有没有办法等待锁链解决?

  • 我和Nodejs一起工作。我有一个异步,因为我必须等待内部的结果。因此,我需要等待foreach完成,然后继续循环的结果。我找到了几个等待的解决方案,其中一个是使用promise。虽然我这样做了,这些promise是创建的,但是,代码后的每个(因此promise)完成,从来没有实际执行(console.log没有打印)。NodeJS函数结束时没有任何错误。 这是我的密码: “here”只打印一次(

  • 我在一个数组上循环,并对一个api进行异步调用,返回的数据需要我与一个不同的数组合并,合并时面临的问题是,一些promise尚未解决,因此合并后产生的数组丢失数据.任何想法如何去做这件事。(我对Angular是新的)。数组循环通过至少有200个元素(我不知道数组的大小提前)我从每个元素获得id,我调用这个服务: 提前谢谢。

  • 我正在努力学习如何正确使用async Wait,但我对它有点共同的想法。 在片段中,我试图构建一个对象数组,其中包含我需要的关于我在组件中上传的文件的信息。问题是this.fileInfo中的对象并没有完全等待返回编码图像的promise,而是在我console.logthis.fileInfo时返回此输出: 如您所见,关键图像是一个值未定义的ZoneAwarePromise。你能帮我修一下吗?

  • 我想在C#中处理子目录和文件的文件系统/文件夹。我正在使用TPL库中的任务。这个想法是递归地执行它并为每个文件夹创建一个任务。主线程应该等待子线程完成,然后打印一些信息。事实上我只是想知道扫描何时完成。我已经开始使用线程池,然后切换到TLP。做了一些简单的例子。经过一些尝试从简单的代码到越来越臃肿的代码我被困在这里: 主线程有时仍然过早地继续,而不是在完成所有其他线程之后继续。(我对C#比较陌生,