通过$ emit('fetch',resolve)以不可预测的方式返回承诺

时间:2019-03-15 19:26:34

标签: javascript vue.js promise

有时this.companies将获得更新,有时不会:

parent component

   fetchCompanies (resolve) {
      this.$store.state.backend
        .get('/jobBuilder/company/all')
        .then(ret => {
          console.log('companies fetched')
          this.companies = ret.data
          if(resolve){
            resolve('resolved')
          }
        })
        .catch(error => console.error(error))
    }

child component

    toggleActivation (button, company) {
      button.disabled = true

      let fetch = new Promise((resolve) => this.$emit('fetch', resolve)) //which activated fetchCompanies in parent

      this.$store.state.backend
        .post('/admin/update-activation/company', {
              id: company.id,
              active: !company.active
        })
        .then(() => fetch)
        .catch(err => alert(err))
        .finally(() => button.disabled = false) 
    }

我不确定为什么,但是API调用的顺序不符合我的要求:

companies fetched
XHR finished loading: GET "http://localhost/jobBuilder/company/all"
companies watch activated
resolved
XHR finished loading: POST "http://localhost/admin/update-activation/company"

实际位置:

XHR finished loading: POST "http://localhost/admin/update-activation/company"
XHR finished loading: GET "http://localhost/jobBuilder/company/all"
companies watch activated
companies fetched
resolved

我不确定自己在做什么错,为什么有时却行不通。

1 个答案:

答案 0 :(得分:1)

您可以尝试执行此操作,该操作基本上将回调作为fetch事件的参数发送:

/**
 * @param {Object} button
 * @param {Object} company
 */
toggleActivation(button, company) {
    this.$emit('fetch', () => {
        // NOTE HERE: we wrap this call in its own function,
        // because if we do not, the promise gets executed and its result is sent.
        this.storeCompany(company);
    });
},
/**
 * @param {Object} company
 * @return {Promise}
 */
storeCompany(company) {
    return this.$store.state.backend
        .post('/admin/update-activation/company', {
              id: company.id,
              active: !company.active
        });
}

然后您的父组件可以执行以下操作:

/**
 * @param {Function} after
 * @return {Promise}
 */
fetchCompanies(after) {
    return this.$store.state.backend
        .get('/jobBuilder/company/all')
        .then(after);
}

如果您记得编写少量可管理的代码(例如始终从函数返回Promise),则可以使其更易于理解,并且更容易将它们链接在一起。