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

Angular$q Service-限制promise数组的并发

蒋承教
2023-03-14

可能有助于为这个问题提供一点背景上下文:我正在构建一个角服务,它有助于将多部分表单数据(mp4视频)块上传到云中的存储服务。

我试图限制同时发生的未解决promise(PUTchunk data请求)的数量。我使用的是$q.all(myArrayOfPromises)。然后()侦听正在解析的所有区块上载promise,然后在发生这种情况时返回异步调用(POST以完成文件)。我认为我的算法遇到了竞争条件,因为$q.all()在为具有大量块的文件安排所有作业之前被调用,但在较小的文件中成功调用。

这是我的算法。

var uploadInChunks = function (file) {
   var chunkPromises = [];
   var chunkSize = constants.CHUNK_SIZE_IN_BYTES;
   var maxConcurrentChunks = 8;
   var startIndex = 0, chunkIndex = 0;
   var endIndex = chunkSize;
   var totalChunks = Math.ceil(file.size / chunkSize);
   var activePromises = 0;

   var queueChunks = function () {
      while (activePromises <= maxConcurrentChunks && chunkIndex < totalChunks) {
         var deferred = $q.defer();
         chunkCancelers.push(deferred); // array with broader scope I can use to cancel uploads as they're happening

         var fileSlice = file.slice(startIndex, Math.min(endIndex, file.size));

         chunkPromises.push(addChunkWithRetry(webUpload, chunkIndex, fileSlice).then(function () {
           activePromises--;
           queueChunks();
        });

        activePromises++;
        startIndex += chunkSize;
        endIndex += chunkSize;
        chunkIndex++;
     }
  }

  queueChunks();

  return $q.all(chunkPromises).then(function () {
     return filesApi.completeFile(file.fileId);
  });
};

尽管过早调用了$q.all,但此时仍挂起/甚至未计划的文件块最终会执行并成功解析。

我已经阅读了大量关于限制$q的并发性的书籍,并且知道有一些库可以提供帮助,但我真的很想了解为什么这不能一直起作用:)

共有1个答案

章哲彦
2023-03-14

您要返回的promise($q.all)实际上并不表示您真正想要返回的promise。在上面的代码中,返回的promise将在第一个maxConcurrentChunks得到解决后完成,因为当您将其传递给$q.all()时,chunkPromises中有多少promise。

处理此问题(并获得所需结果)的另一种方法是以下psuedocode:

var uploadInChunks = function(file){

    //...vars...
    var fileCompleteDeferral = $q.defer();

    var queueChunks = function(){
        chunkPromises.push(nextChunk(chunkIndex).then(function () {
            activePromises--;

            if(allChunksDone()) { //could be activePromises == 0, or chunkIndex == totalChunks - 1
                fileCompleteDeferral.resolve();
            }
            else {
                queueChunks();
            }
        });
    }

    return fileCompleteDeferral.promise.then(completeFile());
}

此代码返回的promise只有在完成所有promise后才能解析,而不仅仅是前8个promise。

 类似资料:
  • 有没有办法限制节点js中一次执行的并发Qpromise的数量? 我正在构建一个web scraper,它必须请求并解析3000多个页面,并且在没有限制的情况下,我提出的一些请求没有及时响应,因此连接停止,所需的响应(html代码)变得不可用。 为了解决这个问题,我发现限制请求的数量可以解决我的问题。 我曾尝试过以下方法,但均无效: Qpromise中的并发限制-节点 我需要请求一个URL数组,一次

  • 我正在寻找一个promise函数包装,它可以在给定的promise运行时限制/节流,以便在给定的时间只运行该promise的一组数量。 在以下情况下,不应同时运行,它们应按照先到先得的顺序一次运行一个。 关于如何设置这样的队列有什么想法吗? 我有一个来自奇妙的的“去盎司”功能。我需要修改它,以限制基于自身执行的promise,而不是延迟。

  • Promise的限制 本节中我们将要讨论的许多细节已经在这一章中被提及了,但我们将明确地复习这些限制。 顺序的错误处理 我们在本章前面的部分详细讲解了Promise风格的错误处理。Promise的设计方式——特别是他们如何链接——所产生的限制,创建了一个非常容易掉进去的陷阱,Promise链中的错误会被意外地无声地忽略掉。 但关于Promise的错误还有一些其他事情要考虑。因为Promise链只不

  • 是否有一种方法/pattern来实现? promise-数组包含构造和返回promise的函数 应在所有解析后解析 只有promise应并行运行 第n+1个promise应在n个完成后立即开始。以便始终有解析器并行运行。

  • 请问一下,在看到一个方法的定义时候: 有返回:Promise<IFileStatResult[]> 请问这个泛型的限制:<IFileStatResult[]> 是限制Promise的什么?限制它的返回信息还是处理的什么呢? === 我找到一个示例:看起来是限制入参。

  • 有没有使用Qpromise库限制promise并发的方法? 这个问题有点与如何限制Qpromise并发有关? 但问题是我正试图这样做: 真正的用例是: 从DB获取帖子 循环DB中的每个帖子,如 对于每个帖子做task1,task2,task3(检索社交计数器,检索评论计数等) 在DB中保存新的文章数据。 但问题是node同时执行所有帖子的所有任务,比如同时向facebook询问500篇帖子的“喜欢