【问题标题】:Data flow and Memory problem in Typescript Promise loopTypescript Promise 循环中的数据流和内存问题
【发布时间】:2021-08-29 12:20:46
【问题描述】:

我正在做一个项目,我必须从 Azure DevOps 存储库中读取大约 3000 多个 JSON 文件,并将它们的内容存储在一个字符串中,以便以后使用。

以下是我用来获取存储库中项目列表的方法。我不允许假设任何目录层次结构,所以我将recursionLevel 参数设置为完整。

文档链接:https://docs.microsoft.com/en-us/javascript/api/azure-devops-extension-api/gitrestclient#getitems-string--string--string--versioncontrolrecursiontype--boolean--boolean--boolean--boolean--gitversiondescriptor-

function getItems(repositoryId: string, project?: string, scopePath?: string, recursionLevel?: VersionControlRecursionType, includeContentMetadata?: boolean, latestProcessedChange?: boolean, download?: boolean, includeLinks?: boolean, versionDescriptor?: GitVersionDescriptor)

上面的函数返回一个 Promise of Git 项目列表,从中我可以从存储库的根目录中获取每个文件的相对路径

在获得项目列表后,我想逐个阅读它们并将它们的内容存储在一个字符串中。为此,我正在使用这种方法:

function getItemText(repositoryId: string, path: string, project?: string, scopePath?: string, recursionLevel?: VersionControlRecursionType, includeContentMetadata?: boolean, latestProcessedChange?: boolean, download?: boolean, versionDescriptor?: GitVersionDescriptor, includeContent?: boolean, resolveLfs?: boolean)

这个功能也可以在我之前分享的同一个链接中使用。你必须向下滚动一点。 它将内容作为字符串的 Promise 返回。

我读取所有文件的代码:

AdoClient.getInstance().getItems(this.repoID, this.projectName, this.commonData.inputBranchName).then(data=>{
            data.forEach(element => {
                if(element.gitObjectType==3)
                {
                   AdoClient.getInstance().getItemText(this.repoID,element.path,this.commonData.inputBranchName).then(element=>{ content.concat(element);
});})});

在上面的代码中:

  1. gitObjectType=3 表示文件
  2. 你看到的函数getItems()和getItemText()其实是我的函数。我写了一个定义来传递 3 个必需的参数。在 AdoClient 文件中,我使用 GitRestClient 对象对函数进行了原始调用,就像您在文档中一样。

这是 AdoClient 文件中的原始函数调用:

public async getItemText(repoId: string, filePath: string, branchName: string) {
        return this.gitClient.then(client => client.getItemText(repoId, filePath, null, null, 'none', false, false, false, {version: branchName, versionOptions: 0, versionType: 0}));
    }

public async getItems(repositoryId: string, project: string,branch: string){
        return this.gitClient.then(client=>client.getItems(repositoryId, project, "/ServiceGroupRoot/", 'full', true, false, false, true, {version: branch, versionOptions: 0, versionType: 0}));
    }

另外请注意/ServiceGroupRoot/ 是我存储库中的根目录。

当我这样做时,我无法获取 content 变量中的所有内容,而且由于同时有 3000 多个 ajax 调用,Google chrome 也显示 ERR_INSUFFICIENT_RESOURCES。此错误不会出现在 Mozilla 中。但是在 Mozilla 中,当我打印内容时,它会显示空字符串。我想要的是一种对我的执行步骤进行排序的方法,以便我可以在我的内容字符串中包含所有内容。有没有办法运行一个 Promise 调用循环并让它们一个一个地执行?一个接一个,我的意思是完成一个然后开始下一个,而不是一次加载所有内容,还是我必须遵循其他方法?

【问题讨论】:

    标签: javascript typescript promise azure-devops-rest-api


    【解决方案1】:

    我想最简单的方法就是使用 for 循环和 await:

    const work = i => {
      return new Promise(resolve => {
        setTimeout(() => resolve(i), Math.floor(Math.random() * 100));
      });
    };
    
    const array = Array(10).fill(0).map((_, i) => i + 1);
    
    // non sequencial
    const test_then = () => {
      array.forEach(i => {
        work(i).then(i => {
          console.log(i);
        });
      });
    };
    
    // sequencial
    const test_await = async () => {
      for (let i = 0; i < array.length; i++) {
        console.log(await work(i));
      }
    };
    
    test_then();
    test_await();
    

    【讨论】:

      【解决方案2】:

      代码中有一些严重错误。

      建议使用传统的 for 循环,以便我们可以使用 async await 语法。

      资源部分我不知道,但我在下面粘贴了清晰的代码。

      async function main() {
      let content = '';
      const data = await AdoClient.getInstance().getItems(/* pass params here*/);
      for (let i = 0; i < data.length; i++) {
        if(data[i].gitObjectType==3){
         const result = await AdoClient.getInstance().getItemText(/* pass params here*/); 
         content.concat(result);
        }
      }
      
      return content;
      } // main close
      
      
      const c = main();
      console.log(c);// your output
      

      【讨论】:

        猜你喜欢
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 2019-11-02
        • 1970-01-01
        相关资源
        最近更新 更多