0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[TypeScript]非同期とコールバック関数

Posted at

下のロジックは、api層でajax同期コードを使って「this.url」から取得したデータを
view層にreturnする内容になります。
このように同期処理をしておいた場合、send()が呼び出されてからすぐAPIから応答がありません。
データがいるはずが全くないため、このようなやり方では、実際にデータ処理をすることができません。
このような場合に非同期を通じて対応することができます。

同期コード
  getRequest<AjaxResponse>(): AjaxResponse {
    this.ajax.open('GET', this.url, false); 
    this.ajax.send();
    return JSON.parse(this.ajax.response) as AjaxResponse;
  }

非同期処理のためにajaxがaddEventリスナーを提供します。
"load"が呼び出されるとajax.responseに応答値が入っていることがわかります。
ここで問題は!同期コードを見ると、応答値をリターンしますが、
非同期コードではリターンする対象がないことが問題になります。
この場合は、「コールバック」関数を受け取って、
そのコールバック関数を通じて呼び出し元に値を伝えれば良いです。

非同期コード
    // コールバック関数を"callback"にて受取って、AjaxResponseタイプのdataを引数にて渡します。
    // コールバック関数のtypeはvoid!
    // callbackで受け取ったコールバック関数にJSON.parseしたデータを引数にてヨビダシ元に!
    // callback: (data: AjaxResponse) == コールバック関数: 引数:引数のタイプ
    getRequest<AjaxResponse>(callback: (data: AjaxResponse) => void): void {
      this.ajax.addEventListener('load', () => {
        callback(JSON.parse(this.ajax.response) as AjaxResponse);
      });
      this.xhr.send();
    }

下のロジックは、api層に存在してて
view層 → getData() → getRequest() です。
api層であるため、実際のデータを受ける側は、viewのため
viewから受取ったコールバック関数をそのままgetRequset渡しています。

getRequest()呼び出し元
  // 同期コード
  getData(): NewsDetail[] {
    return this.request<NewsDetail[]>();
  }

  // 非同期コード
  getData(callback: (data: NewsDetail) => void): void {
    return this.getRequest<NewsDetail>(callback);
  }

以下はview層の非同期対応コードです。
view層
    // 同期コード
    render = (id: string): void => {
      const api = new NewsDetailApi(CONTENT_URL.replace('@id', id));
      const {title, content, comments } = api.getData();
    }

    // 非同期コード
    // 非同期コードに修正したgetData()は、もうreturnをしなくなったので
    // getData()にコールバック関数を渡します。
    // 結局、getRequestの「JSON.parse(this.ajax.response) as AjaxResponse)」の結果 == data
    // になります!
    render = (id: string): void => {
      const api = new NewsDetailApi(CONTENT_URL.replace('@id', id));
      api.gatData((data: NewsDetail) => {
        const {title, content, comments } = data;
        this.store.makeRead(Number(id));
        this.setTemplateData('comments', this.makeComment(comments));
        this.setTemplateData('currentPage', this.store.currentPage.toString());

        this.updateView();
      })
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?