为什么Promise api调用未传递正确的数据元素?

时间:2019-07-18 16:26:51

标签: angular asynchronous promise

我有以下服务方法:

public getConf() : Promise<string[]> {
let rows : string[] = [];

  this.dao.getData(SearchCriteria.getRecordsFrom("EcegConfig")).then(configs => {
    configs.forEach((cfg : EcegConfRecord) => {
      console.log("START", cfg.data.ecegconf);
      let tmp = cfg.data.ecegconf;
      rows.push(tmp);
    });
  });

return of(rows).toPromise();}

以及ngOnInit()中我组件中的以下代码块:

 this.http.getConf().then(data => {
  console.log("D A T A", data, data.length, data[0]);
});

我可以在数据中看到正确的字符串,但是长度为0并且data [0]未定义,并且我无法在数据上使用forEach。 另外START console.log也为我提供了正确的字符串项目。

(我知道我使用return of(rows).toPromise()可能很不寻常,我只是从Observable输出开始,但这不应该是错误的吗?或者我在其他一些方法中使用了它如预期的那样工作)

据我了解的承诺,.then()等待服务方法的返回完成,或者?因此数据中应该包含元素?所以我在某处可能有类型错误? (但是正如我所说的START提供正确的字符串,这是我要压入行中的唯一操作。因此Promise返回类型应该可以还是??

1 个答案:

答案 0 :(得分:0)

让我们用每行执行的时间来注释代码:

public getConf() : Promise<string[]> {
  let rows : string[] = []; // t0

  this.dao.getData(SearchCriteria.getRecordsFrom("EcegConfig")) // t1
    .then(configs => {
      // t10000
      configs.forEach((cfg : EcegConfRecord) => {
        console.log("START", cfg.data.ecegconf);
        let tmp = cfg.data.ecegconf;
        rows.push(tmp);
      });
    });

  return of(rows).toPromise(); // t2
}

一个promise或observable的全部目的是能够注册一个回调,当http请求的响应最终在时间t10000可用时,该回调将被称为 。但是,您创建了一个可观察对象,该对象立即发出空数组并将其转换为promise。这样就行不通了。

我将停止使用Promise并接受可观察的对象,因为在Angular中它们是不可避免的,并且比Promise更强大。如果getData返回一个可观察的,您将需要的全部是

return this.dao.getData(SearchCriteria.getRecordsFrom("EcegConfig")).pipe(
  map(configs => configs.map((cfg : EcegConfRecord) => cfg.data.ecegconf))
);

如果您真的想继续使用承诺,则可以使用

return this.dao.getData(SearchCriteria.getRecordsFrom("EcegConfig")).then(
  configs => configs.map((cfg : EcegConfRecord) => cfg.data.ecegconf)
);