【问题标题】:Weird behaviour of for loopfor循环的奇怪行为
【发布时间】:2019-02-11 17:55:25
【问题描述】:

我有一系列带有货号的产品。

0:"3323"
1:"3319"
2:"3322"
3:"3331"
4:"3309"
5:"3317"
6:"3316"
7:"3329"
8:"3330"
9:"3332"
10:"3324"

我将此数组的每个文章编号传递给服务以获取相应产品的详细信息以显示图像。当我在数组中推送每个产品的图像属性时,每次我在每个索引处获得不同的值。

我希望每篇文章的图像都位于与上述数组相同的索引上。 示例:3323 的图像在新数组的第 0 个索引处。

werbedata: WerbeData[];
produkt: Produkt[];
urls: string[] = [];

  getWerbeData(filialewerbenr) {
    this.werbedataService.getWerbeData(filialewerbenr)
      .then(
        (werbedata) => {
          this.werbedata = werbedata[0];
          this.anums = this.werbedata.ArtNr.split(' ');
          console.log(this.anums);
          for (let i = 1; i < this.anums.length; i++) {
            let articleNumber = this.anums[i];
            this.produktService.getProdukt(articleNumber)
              .then(
                (product) => {
                  this.produkt = product[0];
                  this.urls.push(this.produkt.PfadBild_1);
                }
              );
          }
        },
    )
  }

我在哪里做错了,所以我会在相应的索引中获得相应的产品详细信息?

【问题讨论】:

  • filialewerbenrwerbedataServicegetWerbeData 等是什么?删除与问题无关的所有内容。您提到的产品系列在哪里?
  • @destoryer 这些是我的服务获取产品数据的参数。它是德语的。我正在编辑我的问题。
  • @destoryer 我已经编辑了我的问题

标签: arrays angular typescript for-loop


【解决方案1】:

您可以跟踪所有承诺并等待所有承诺完成。下面的 sn-p 显示了您可以如何执行此操作。

const
  productNumbers = ["3323","3319","3322","3331","3309","3317","3316","3329","3330","3332","3324"];
  
function getWerbeData(id) {
  // Do your webservice call and make sure it returns a promise. This code 
  // will wait between 500ms and 1000ms before returning a fake result.
  console.log(`[${id}] - getting data`);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`[${id}] - data received`);
      resolve(`result for ${id}`)
    }, (Math.random() * 500) + 500);
  });
}

const
  // Creates a new array with for each product number a promise.
  promises = productNumbers.map(productNumber => getWerbeData(productNumber));
  
// Wait for all the promises to be resolved and print a log line.
Promise.all(promises)
  .then(() => console.log('all data retrieved'));

【讨论】:

  • @RuchirNaphade 请注意,如果其中一个承诺失败,Promise.all() 也会失败,并且它不会等到所有承诺都完成后才会这样做。
  • @Thijs...我尝试了您的建议并在承诺失败时遇到了同样的问题...非常感谢您给我这个想法...
【解决方案2】:

一个数组从索引 0 开始。 您的 for 循环以 i = 1 开始。 因此,您总是得到以下物品,而不是您所期望的。

=> for (让 i = 0; i

热烈的问候

更新: 我的错。 您正在迭代数组(同步),但随后您执行异步调用以获取其他数据。 没有保证,第一个调用的异步调用也将是第一个完成的。

所以,最后的顺序很大程度上取决于这个异步调用

 this.produktService.getProdukt(articleNumber)

更新 2: 解决方案是建立一个结果结构。在那里,您必须以正确的顺序交付异步 .getProduct 调用的所有结果。 然后您必须检查所有异步调用是否已完成... 之后,您可以遍历结果结构并以正确的顺序获取数据。

我用 promise 工作了一段时间(我真的很喜欢 rxjs :-)) 因此,将索引信息和计数器传输到 .then 方法中可能会出现问题...

let resultData = [];
let counter = 0;
for (let i = 1; i < this.anums.length; i++) {
        let articleNumber = this.anums[i];
        counter++;
        this.produktService.getProdukt(articleNumber)
          .then(
            (product) => {
              this.produkt = product[0];
              resultData[i] = this.produkt.PfadBild_1;
              counter--;
            }
          );
      }
      // Now wait until counter reaches again 0, than your result structure should be up to date.

【讨论】:

  • 我也试过了,还是不行。有时我会按所需顺序获得所有产品,但有时不会。虽然我从 1 开始我的数组,因为我不希望第一个产品仍然应该以所需的顺序获得剩余的产品,对吗?
  • 对不起我的错误。我更新了我的 anwser,问题是你的循环中的异步调用
  • @JanRecker..谢谢,但我需要在这里做什么?你能提出一些建议吗?一旦 werbedata 服务完成,我应该调用我的 getProduct 服务吗?
  • 我试一试。但是我使用 Promise 已经有一段时间了……看看 rxjs,对于你的问题有很好的解决方案。像 forkJoin(arrayOfRequests).subscribe([正确顺序的结果数组] => 用它做魔法)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多