【问题标题】:can not access the property object Typescript无法访问属性对象 Typescript
【发布时间】:2018-05-11 14:23:00
【问题描述】:

我需要编写一些对象数组和接口数组来使用 Angular 应用程序来完成我的项目,但我必须面对那里的值错误。我尝试了 3 种代码替代方案:

首先

我不明白为什么对象没有返回。

这是我的输出:

这里是代码:

主页组件

  onSearch(){
this.indexingQuery(this.search); // for spliting the input user and check the word
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      console.log(a);
      console.log("a");
      this.termFA.push(a);
    }
    this.termFA.forEach(element=>{
      console.log(element);
      console.log(element.freq);
    });

  }
);}

数据库服务

ReadTermPerDocumentFreq(kata:string):TermFreqAll{
let temp:TermFreqAll ;
this.afDb.database.ref('/term_freq_all/'+kata).
once('value', function(snapshot){
  let userData : any= snapshot.val();
  temp = new TermFreqAll(
    userData.word,
    userData.doc_freq,
    userData.freq,
    userData.docs
  );
  console.log("temp");
  console.log(temp);
  console.log("temp");
});
console.log(temp);
return temp;}

第二

如果我像这样更改该代码。它会被退回,但我无法获得财产。

这是输出:

还有代码:

主页组件

onSearch(){
this.indexingQuery(this.search);
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      this.termFA.push(a);
      console.log(a);
      console.log("a");
    }
    this.termFA.forEach(element=>{
      console.log("Arrghh");
      console.log(element);
      console.log(element.freq);
    });

  }
);}

数据库服务

ReadTermPerDocumentFreq(kata:string):TermFreqAll{
let temp:TermFreqAll = new TermFreqAll();
this.afDb.database.ref('/term_freq_all/'+kata).
once('value', function(snapshot){
  let userData : any= snapshot.val();
  temp.freq = userData.freq;
  temp.docs = userData.docs;
  temp.doc_freq = userData.doc_freq;
  temp.word = userData.word;
  console.log("temp");
  console.log(temp);
  console.log("temp");
});
console.log(temp);
return temp;}

第三

我尝试从数据库服务返回承诺。该值可以推入 TermFA 数组,但不能在循环中获取该值。与第二次尝试相同的情况。它说数组长度为0。

这是我的输出

这是代码:

主页组件

onSearch(){
this.indexingQuery(this.search);
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      console.log(index);
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      a.then((data)=>{
        console.log("data");
        console.log(data);
        let b = this.termFA.push(data);
      });
    }
    console.log("this.termFA");
    console.log(this.termFA);
    this.termFA.forEach(element=>{
      console.log("Arrghh");
      console.log(element);
      console.log(element.freq);
    });
    console.log("this.termFA2");
    console.log(this.termFA);
    for(let i in this.termFA){
      console.log("loop");
      console.log(this.termFA[i]);
      console.log(this.termFA[i].freq);
    }
  }
);}

数据库服务

ReadTermPerDocumentFreq(kata:string):Promise<TermFreqAll>{
return new Promise((resolve, reject)=>{
  this.afDb.database.ref('/term_freq_all/'+kata).once("value",snapshot => {
      let userData : any= snapshot.val();
      // console.log(userData);
      if (userData){
        console.log("userdata");
        console.log(userData);
        let temp : TermFreqAll = new TermFreqAll();
        temp.freq = userData.freq;
        temp.docs = userData.docs;
        temp.doc_freq = userData.doc_freq;
        temp.word = userData.word;
        // console.log("true");
        resolve(temp);
      }
      else{
        let temp : TermFreqAll = new TermFreqAll();
        resolve(temp);
      }
  }).catch(error=>{
      let temp : TermFreqAll = new TermFreqAll();
      resolve(temp);
  });
});}

【问题讨论】:

  • 感谢改进我的话@xg.plt.py
  • 没问题!我对角度和打字稿不太了解,我不确定,但我认为除了您尝试过的代码之外还包括您的 desired output

标签: angular typescript


【解决方案1】:

最后一次尝试的问题是您在第一个循环中调用了一个异步数据库函数。您期望它的结果在每个循环之后已经存在,但事实并非如此,因为 then is 函数是异步的,并且可能稍后会被调用。 现在不是等待结果,而是循环继续触发更多的数据库调用,当它完成时,您尝试访问 termFA 数组,但可能尚未执行填充此数组的结果函数。

这是解决此问题的一个选项。您可以收集这些 Promise 并通过 Promise.all() 调用执行它们,而不是尝试直接对第一个循环中的 Promise 做出反应。通过这种方式,您可以轻松地一次对所有的 Promise 返回做出反应,并在手边拥有一个已完成且已填充的结果数组。

let promiseArray:Promise<TermFreqAll>[]=[];
for(var index in this.term) { 
  console.log(index);
 // save it in an array to combine all executes after the loop has finished
 promiseArray.push(this.dbService.ReadTermPerDocumentFreq(index));
}

// now execute them and wait till they are all returned
Promise.all(promiseArray).then(values=>{
  // when everything has returned, you can react to it as if you had filled your array;
  // "values" is an array of all results, what probably is equal to your "termFA" array
  values.forEach(element=>{
    console.log("Arrghh");
    console.log(element);
    console.log(element.freq);
  });
}

有关Promise.all 功能的更多信息,您可以查看this

希望这会有所帮助。如果有不清楚的地方请告诉我。

【讨论】:

  • 它像@BenediktSchmidt 先生之前一样运行。我试过 = - 我在 let promiseArray=[]; 中添加类型,就像这样 let promiseArray:TermFreqAll=[]; - 从上面的代码中将 this.termFA 更改为 values,结果相同,promiseArray 的长度为 0
  • 我尝试再次调用它let a = this.dbService.ReadTermPerDocumentFreq(index); a.then((data)=&gt;{ //to get atribut }); 它有效。但为什么我必须先打电话。该函数只返回promise&lt;boolean&gt;
  • 我已经更新了我的代码。数组应该是Promise&lt;TermFreqAll&gt;[] 类型,不确定这是否能解决问题。是的,我们当然会在Promise.all() 调用之后循环这些值。
猜你喜欢
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多