api.get(...)。then(...)。catch(...)。最终不是函数

时间:2019-09-11 06:20:46

标签: 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);
      });
  }

但是我遇到以下错误:

TypeError

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

得到的是什么

 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);
  }

8 个答案:

答案 0 :(得分:1)

这很丑陋,但是显式的Promise构造反模式将在这里起作用-如果将axios调用包装在 native new Promise中,则原型链中将包含Promise.prototype.finally

(在较新的环境中)仅保证本机Promise(由new Promise构造)具有.finally方法。 (在较旧的环境中,.finally不适用于使用new Promise创建的承诺)

看来axios在内部不使用new Promise-相反,它只是返回一个thenable,这不能保证具有finally方法(并且因为不会,它会引发错误)。

get(API, params = this.defaultParams) {
  this.call = "GET";
  let constructedURL = this.constructURL(API, params);
  axiosRetry(axios, { retries: this.retry });
  return new Promise((resolve, reject) => {
    axios.get(constructedURL, this.config)
      .then(resolve)
      .catch(reject)
  });
}

答案 1 :(得分:1)

我建议使用另一个then而不是finallythen之后的catch的工作方式类似于finally。不要忘记在您的诺言链中使用至少一个catch,以处理您的指令失败。

所以这两行代码是相同的:

api.get(…).then(…).catch(…).then(...)

api.get(…).then(…).catch(…).finally(...)

答案 2 :(得分:0)

像这样在您的get函数中传递api:

<v-form @submit.prevent="login" v-model="valid" ref="form">
  <v-text-field
    prepend-icon="person"
    name="login"
    :label="$t('Login')" <-- This line is still translated automatically
    type="email"
    v-model="email"
    :rules="[v => !!v || $t('E-mail is required')]" <-- This line is not translated automatically
  ></v-text-field>
  ...
</v-form>

答案 3 :(得分:0)

promise应该采用es6中的finally,我不确定axios promise是否会支持该承诺,如果可以的话,我建议使用then而不是{ {1}}

finally

答案 4 :(得分:0)

我曾经遇到过类似的问题,但是它是Firefox独有的,但是在解决或拒绝后我仍然需要做一些代码,因此我使用了async/await格式。

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);
(async () => {
    try {
        const response = await api.get("merchantMessages", { repl_str: merchantId })
        this.merchantMessageConfiguration(response.data)
    } catch (error) {
        console.log(error);
    } finally {
        self.state.list.push(
            <Card
                merchant={self.props.merchant}
                key={self.props.merchant.id}
                bubblemsg={self.state.bubblemsg}
            />
       );
    }  
})()
}

答案 5 :(得分:0)

var url = 'https://api.github.com/users/hadley/orgs';
fetchJson(url)
.then((obj) =>{ 
    console.log('obj') 
    console.log(obj) 
    console.log('obj') 
})
.catch((error) =>{ 
    console.log('error') 
    console.log(error) 
    console.log('error') 
})
.finally(() => { 
    console.log('WHALE HELLO THERE ?') 
});

答案 6 :(得分:0)

您可以将其添加到代码开头的某处:

if (Promise.prototype.finally == null) {
    Promise.prototype.finally = function (handler) {
        return this.then(handler, handler);
    }
}

小提琴测试:https://jsfiddle.net/m63kgq7f/

答案 7 :(得分:-2)

尽量避免使用.finally()。就是这样。