api.get(...).then(...).catch(...).finally 不是函数

Cec*_*uez 13 javascript reactjs react-native

我正在调用 React Native API。

理论上它应该工作 -

    import API from "../../utils/API";

  componentDidMount() {
    let merchantId = this.props.merchant.id;
    let api = new API(this.props.gatheredTokens);
    let self = this;
    api.setRetry(10);
    api
      .get("merchantMessages", { repl_str: merchantId })
      .then(response => this.merchantMessageConfiguration(response.data))
      .catch(function (error) {
        console.log(error);
      })
      .finally(function () {
        self.state.list.push(
          <Card
            merchant={self.props.merchant}
            key={self.props.merchant.id}
            bubblemsg={self.state.bubblemsg}
          />
        );
      })
      .finally(function () {
        self.merchantNoticeLoading(self);
      });
  }
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

类型错误

是什么导致了这个错误?该代码看起来有效。

这是得到的是:

 get(API, params = this.defaultParams) {
    this.call = "GET";
    let constructedURL = this.constructURL(API, params);
    axiosRetry(axios, { retries: this.retry });
    return axios.get(constructedURL, this.config);
  }
Run Code Online (Sandbox Code Playgroud)

Sad*_*ori 17

我建议使用另一个then而不是使用finally. then之后catch就像一个finally. 不要忘记catch在您的承诺链中至少使用一个,以处理您的指令失败。

所以这两行代码是一样的:

api.get(…).then(…).catch(…).then(...)
Run Code Online (Sandbox Code Playgroud)

api.get(…).then(…).catch(…).finally(...)
Run Code Online (Sandbox Code Playgroud)

  • 这有效。但是,如果我正在为现代浏览器开发现代应用程序并且此方法已在 MDN 中记录,为什么我不能使用 finally() 呢? (5认同)

Cer*_*nce 8

只有原生 Promise(用 构造new Promise)才能保证有一个.finally方法(在较新的环境中)。(在较旧的环境中,.finally根本无法使用使用 创建的 Promise new Promise

看起来 axios并没有在内部使用new Promise- 相反,它只是返回一个 thenable,它不保证有一个finally方法(因为它没有,所以它会抛出一个错误)。

虽然您可以使用显式的 Promise 构造反模式将 axios 调用包装在 native 中 new Promise以便它Promise.prototype.finally在其原型链中,但更好的选择(感谢 Bergi!)是仅使用Promise.resolve,这会将 thenable 转换为本机 Promise,而保留thenable的失败或成功:

get(API, params = this.defaultParams) {
  this.call = "GET";
  let constructedURL = this.constructURL(API, params);
  axiosRetry(axios, { retries: this.retry });
  return Promise.resolve(axios.get(constructedURL, this.config));
}
Run Code Online (Sandbox Code Playgroud)

  • 您仍然应该避免 [`new Promise` 构造函数反模式](/sf/ask/1666262041/?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) 。要将 thenable 强制为原生 Promise,只需编写“return Promise.resolve(axios.get(…));”,仅此而已。 (2认同)