【问题标题】:Get request using loop使用循环获取请求
【发布时间】:2019-02-03 10:49:35
【问题描述】:

有这样的问题。

我正在尝试使用循环在 Wikipedia API 中发出一定数量的 GET 请求。 尝试使用 getAllInfo() 函数来做到这一点

articles.components.ts

export class ArticlesComponent {
  constructor(private articlesServices: ArticlesService) { }

  @Input() allTitles: string[];

  articlesInfo: ArticleInformationNew;
  allArray: [[string, number]] = [['', 0]];

  static getUrlInformation(searchQuery: string) {
    return 'https://ru.wikipedia.org/w/api.php?action=query&titles='
      + searchQuery + '&prop=info&format=json&origin=*';
  }

  getAllInfo() {
    for (const title of this.allTitles) {
      this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
        .subscribe(
          (data: ArticleInformation) => this.articlesInfo = {
            ...data,
            query: { pages: [Object.values(data.query.pages)[0]]}}
        );
        this.allArray.push([this.articlesInfo.query.pages[0].touched, this.articlesInfo.query.pages[0].length]);
    }
  }
}

articles.service.ts

export interface ArticleInformation {
  batchComplete: string;
  query: {
    pages: {
    }
  };
}

export interface ArticleInformationNew {
  batchComplete: string;
  query: {
    pages: any[]
  };
}

export class ArticlesService {
  constructor(private http: HttpClient) { }

  getArticleInformation(url) {
    return this.http.get<ArticleInformation>(url);
  }
}

数组this.allTitles 可以由多行组成。 例如this.allTitles = ['Naumen', 'Naumen DMS']

我希望数组this.allArray 是二维的,并且包含由每个查询的数据行组成的数组。 例如

this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-01-21T04:24:21Z', 9704]

但事实上,二维数组的每个元素都是一样的。 例如

this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-02-01T23:27:26Z', 3687]

为什么以及如何解决它?

【问题讨论】:

  • HTTP 请求是异步的。您必须在订阅中更新数组。
  • @Arcteezy 嗨,又是我。你昨天帮了我很多:D你能告诉我具体写什么吗?

标签: arrays angular typescript get httprequest


【解决方案1】:

试试这个,

getAllInfo() {
    for (const title of this.allTitles) {
      this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
        .subscribe(
          (data: ArticleInformation) => {
            this.articlesInfo = {
                ...data,
                query: { pages: [Object.values(data.query.pages)[0]]}
            }
            this.allArray.push([this.articlesInfo.query.pages[0].touched,this.articlesInfo.query.pages[0].length]);
          } 
        );

    }
  }

【讨论】:

  • 非常感谢,朋友!爱你,你第二次救了我。
【解决方案2】:

你可以使用combineLatesthttps://www.learnrxjs.io/operators/combination/combinelatest.html

首先,收集要组合的 observables(但不订阅它们),然后将它们与 combineLatest 组合并以 array 的形式获取响应并对其进行迭代。

getAllInfo() {
    console.log(this.allTitles);

    observablesToSubscribe = [];

    for (const title of this.allTitles) {
      observablesToSubscribe.push(this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title)));
    }

   combineLatest(observablesToSubscribe).subscribe((responseData: Array<ArticleInformation>) => {
       responseData.forEach((responseDatum) => {
           this.allArray.push({
              ...data,
              query: { pages: [Object.values(data.query.pages)[0]]}
           })
       });   
   });     
}

【讨论】:

    【解决方案3】:

    也许,我误解了这个问题,但是您可以通过更正您的searchQuery(使用替代分隔符作为标题)来获得具有特定标题的页面,并摆脱for loop

    getAllInfo() {
      console.log(this.allTitles);
    
     this.articlesServices.getArticleInformation(
       ArticlesComponent.getUrlInformation(this.allTitles.join('|'))
         .subscribe(
           (res => {
             // here is a result with all pages of particular titles,
             // then you can process your result...
             console.log(res);
    
             // this.allArray is a multidimensional array
             // [["2019-01-25T00:45:06Z",4508],
             // ["2019-01-26T07:25:08Z", 773]]
             this.allArray = Object.keys(res.query.pages)
               .reduce((acc, val, index) => {
                 acc[index] = [pages[val].touched, pages[val].length];
                 return acc;
               }, []);
         });
    }
    

    searchQuery 的标题在这种情况下将是 Naumen | Naumen DMS(而不是,例如,只是 Naumen)。 | (pipe) 是标题的替代分隔符。

    处理结果(res.query.pages):

    const pages = {
      "755288": {
        "pageid": 755288,
        "ns": 0,
        "title": "Spring",
        "contentmodel": "wikitext",
        "pagelanguage": "ru",
        "pagelanguagehtmlcode": "ru",
        "pagelanguagedir": "ltr",
        "touched": "2019-01-26T07:25:08Z",
        "lastrevid": 84434967,
        "length": 773
      },
      "92586": {
        "pageid": 92586,
        "ns": 0,
        "title": "Atom",
        "contentmodel": "wikitext",
        "pagelanguage": "ru",
        "pagelanguagehtmlcode": "ru",
        "pagelanguagedir": "ltr",
        "touched": "2019-01-25T00:45:06Z",
        "lastrevid": 95248014,
        "length": 4508
      },
    };
     
    const arr = Object.keys(pages).reduce((acc, val, index) => {
      acc[index] = [pages[val].touched, pages[val].length];
      return acc;
    }, []);
    
    console.log(arr);

    【讨论】:

    • 是的,它有效,但正因为如此,我的past problem appears
    • @Ilya Nizovcev 我添加了对结果的处理,因此您将在一个请求中拥有多维数组
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2021-11-03
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多