【问题标题】:How to use 'this' in Promise?如何在 Promise 中使用“this”?
【发布时间】:2021-10-28 12:23:26
【问题描述】:

我正在尝试在 Promise 函数中发出 http 请求。 我得到this.http.postundefined error... 我知道我必须以某种方式访问​​this,但我不明白该怎么做。

有人愿意帮助我吗?

doUpload(files: Array<File>): Promise<Array<UploadResult>> {
    console.log(files);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        let result: Array<UploadResult> = [];
        for (let file of files) {
          this.http
            .post(this.APIURL + "/image/upload/markdown", file)
            .subscribe((data) => {
              console.log(data);
            });
          result.push({
            name: file.name,
            url: `https://avatars3.githubusercontent.com/${file.name}`,
            isImg: file.type.indexOf("image") !== -1,
          });
        }
        resolve(result);
      }, 3000);
    });
  }

错误:

> TypeError: undefined is not an object (evaluating 'this.http.post')  
> (anonyme Funktion) — sensor-edit.component.ts:308  
> onInvokeTask — core.js:39680  
> runTask — zone-evergreen.js:168  
> invokeTask — zone-evergreen.js:465  
> timer — zone-evergreen.js:2650

构造函数:

constructor(
    private fb: FormBuilder,
    private route: ActivatedRoute,
    private api: ApiService,
    private _routerService: Router,
    private errorService: ErrorModalService,
    private sanitizer: DomSanitizer,
    private http: HttpClient
  ) {}

doUpload 在我的 Html 中是这样调用的:

<div class="container well come-space">
          <md-editor formControlName="markdown" name="Content" [height]="'400px'" [upload]="doUpload">
          </md-editor>
</div>

【问题讨论】:

  • 可以添加错误堆栈吗?箭头函数会自动指向正确的词法范围。它应该可以正常工作。
  • 另外,登录this.http。它似乎指向某个对象,但不是您期望的对象。
  • 当然。刚刚编辑了问题。当我登录this.http 时,它显示undefined..
  • 请向我们展示您的组件的constructor 以及声明该组件的模块声明。
  • 你能显示调用doUpload 的代码吗?

标签: angular typescript post httpclient undefined


【解决方案1】:

TBH,我看不到将 Observable 转换为 Promise 的用途。事实上,目前您正在创建多个可以保持打开状态的订阅。相反,我会使用 RxJS forkJoin 在单个订阅中并行触发多个可观察对象。

试试下面的

import { forkJoin, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

doUpload(files: Array<File>): Observable<Array<UploadResult>> {
  return forkJoin(                                  // <-- RxJS `forkJoin` function
    files.map((file: any) =>                        // <-- `Array#map` function
      this.http.post(
        this.APIURL + "/image/upload/markdown", 
        file
      ).pipe(
        map((data: any) => ({                       // <-- RxJS `map` operator
          name: file.name,
          url: `https://avatars3.githubusercontent.com/${file.name}`,
          isImg: file.type.indexOf("image") !== -1,
        }))
      )
    )
  );
}

那你就可以订阅了

this.doUpload(files).subscribe({
  next: (response) => console.log(response),
  error: (error) => console.log(error)
});

更新

正如 cmets 所述,我的解决方案不能与 &lt;md-editor&gt;@Input() upload 变量结合使用。使用您自己的 doUpload() 实现和以下 sn-p 组件的构造函数。

constructor() {
  this.doUpload = this.doUpload.bind(this);
}

取自ngx-markdown-editor's docs

【讨论】:

  • 虽然您的回答是正确的陈述,但它并不能回答实际问题。
  • 谢谢.. 但现在我收到此错误undefined is not a function (near '...files.map...')
  • 我没有意识到您将doUpload() 函数作为@Input 传递给&lt;md-editor&gt;。在这种情况下,我的解决方案将不适用。尝试使用 doUpload() 函数的初始实现在组件的构造函数中执行 this.doUpload = this.doUpload.bind(this);。取自他们的docs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 2012-11-27
  • 1970-01-01
相关资源
最近更新 更多