読者です 読者をやめる 読者になる 読者になる

async function でfetchをラップする関数を作る

TypeScript

javascriptで async function の使い方を勘違いしていたようなのでメモ。

先に正しく動く例

export class ApiWrapper {

  public async getResult = (searchText: string) => {

    let myHeaders = new Headers({
      'Token': ''
    });

    const response = fetch(this.apiUrl + searchText, {
      method: 'GET',
      headers: myHeaders,
      mode: 'cors',
      credentials: 'include'
    });

    if (response.status >= 200 && response.status < 300) {
      let data = await response.json();
      return data;
    } else {
      var error = new Error(response.statusText);
      throw error
    }
  }
}

呼び出し側

let hoge = async () => {
  const apiWrapper = new ApiWrapper();
  const fuga = await apiWrapper.getResult('検索したいワード');
  console.log(fuga);
}

何を勘違いしていたのか

functionの前に async を付けて、戻り値は Promiseにすればいいと思っていた。

export class ApiWrapper {

  // タグ一覧取得
  public async getResult = (searchText: string) => {

    let myHeaders = new Headers({
      'Token': ''
    });

    return fetch(this.apiUrl + searchText, {
      method: 'GET',
      headers: myHeaders,
      mode: 'cors',
      credentials: 'include'
    }).then( (response) => {
      if (response.status >= 200 && response.status < 300) {
        return response.json();
      } else {
        var error = new Error(response.statusText);
        throw error
      }
    }).then( (data: any) => {
      console.log('success');
      return data;
    }).catch( (error) => {
      console.log('request failed', error);
      throw error;
    });
  }
}

と書いて、Promiseを返してあげればいいのではと思ってましたが、この場合、呼び出し側では下の様に書かなければいけなくて冗長だなと思ってました。

let hoge = async () => {
  const apiWrapper = new ApiWrapper();
  apiWrapper.getTagList('tag name')
  .then( (response) => {
    console.log(response);
  })
  .catch( (error) => {
    console.log(error);
  });
}

でもこれは勘違いで、 ApiWrapper は Promise を返す Promise になっていただけでした。

これは、 c# だと Task<Task<T>> になっている、と言われてなるほどと思いました。