Vuex action which returns a promise never resolves or rejects

浪子不回头ぞ 提交于 2020-02-06 04:43:37

问题


I'm trying to build up my API service in my VueJS application by using Vuex. I'm in the process of refactoring some stuff to centralize error handling, clean-up, etc. The issue I'm running into is properly chaining Promises through my function calls.

At the root level, I have a BaseService class, which simply make API requests using AXIOS (not full class):

export abstract class BaseService {
  protected readonly API: AxiosInstance; // Full init left out

  protected deleteItem(url: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.API.delete(url)
        .then((response: any) => {
          resolve(response);
        })
        .catch((error: any) => {
          this.handleError(error); // Local function that logs error
          reject(error);
        });
    });
  }
}

Then I have one layer above which managers different features of the API by assembling the request URL and handling the data:

class CompanyService extends BaseService {
  private constructor() {
    super();
  }

  public delete(id: number): Promise<any> {
    return this.deleteItem(`${this.baseUrl}/api/companies/${id}`);
  }
}

Then in my Vuex action I'm calling the companyService delete function:

const action = {
  COMPANY_DELETE(context: any, id: number) {
    return new Promise((resolve, reject) => {
      companyService // Instance of CompanyService
        .delete(id)
        .then((response: any) => {
          console.log(response); // This logs successfully
          resolve(response);
        })
        .catch((error: any) => {
          console.log(error); // This logs successfully
          reject(error);
        });
    });
  }
};

The two console logs complete successfully as indicated by my comments. This issue comes in when I get to the component which invokes this action:

this.$store
  .dispatch("company/COMPANY_DELETE", company.id) // Namespaced
  .then((response: any) => {
    console.log(response); // Never gets called
  })
  .catch((error: any) => {
    console.log(error); // Never gets called
  });

Those two console logs are never called. What am I doing wrong here?


回答1:


Small example to demonstrate an action with axios without an extra promise wrap...

const store = new Vuex.Store({
	state: {
  	followers: 0
  },
  mutations: {
  	updateFollowers(state, followers){
    	state.followers = followers;
    }
  },
  actions: {
    getFollowers({commit}) {
        return axios.get('https://api.github.com/users/octocat').then( (response) => {
        	commit("updateFollowers", response.data.followers);
          return "success!!!";
        });
    }
  }
})

Vue.component('followers', {
  template: '<div>Followers: {{ computedFollowers }}</div>',
  created () {
    this.$store.dispatch('getFollowers').then( (result) => {
    	console.log(result);
    });
  },
  computed: {
  	computedFollowers() {
    	return store.state.followers;
    }
  }
});

const app = new Vue({
	store,
  el: '#app'
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
  <followers></followers>
</div>



回答2:


What ended up working was to remove the extra Promise like Void Ray said. However, in my particular use-case I also need to support error propagation. So the below action contains the fixes that I needed to make.

const action = {
  COMPANY_DELETE(context: any, id: number) {
    return companyService // Instance of CompanyService
      .delete(id)
      .then((response: any) => {
        console.log(response);
      })
      .catch((error: any) => {
        console.log(error);
        throw error; // Needed to continue propagating the error
      });
  },
};


来源:https://stackoverflow.com/questions/50989588/vuex-action-which-returns-a-promise-never-resolves-or-rejects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!