返回承诺的 Vuex 操作永远不会解析或拒绝
Posted
技术标签:
【中文标题】返回承诺的 Vuex 操作永远不会解析或拒绝【英文标题】:Vuex action which returns a promise never resolves or rejects 【发布时间】:2018-12-02 00:41:47 【问题描述】:我正在尝试使用 Vuex 在我的 VueJS 应用程序中构建我的 API 服务。我正在重构一些东西以集中错误处理、清理等。我遇到的问题是通过我的函数调用正确链接 Promise。
在根级别,我有一个 BaseService 类,它只是使用 AXios(不是完整类)发出 API 请求:
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);
);
);
然后我在上面有一层,通过组装请求 URL 和处理数据来管理 API 的不同功能:
class CompanyService extends BaseService
private constructor()
super();
public delete(id: number): Promise<any>
return this.deleteItem(`$this.baseUrl/api/companies/$id`);
然后在我的 Vuex 操作中,我调用 companyService 删除函数:
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);
);
);
;
如我的 cmets 所示,两个控制台日志已成功完成。当我到达调用此操作的组件时,就会出现此问题:
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
);
永远不会调用这两个控制台日志。我在这里做错了什么?
【问题讨论】:
不完全了解您的代码库是"company/COMPANY_DELETE"
正确的操作名称吗?不应该是"COMPANY_DELETE"
是的,存储模块是命名空间的。那是正确的名字。在重构之前,我没有 Base 和 Company 服务,所以一切都在行动中并且按预期工作。调用动作的组件没有改变。重构的目的是整理存储,提高可重用性和错误处理能力。
您的控制台中是否收到任何错误消息?
在构建期间或控制台中没有错误消息或警告。
最好在您的功能旅程中放置几个断点,以查看它在哪个点中断。
【参考方案1】:
使用 axios 演示操作的小示例,无需额外的承诺包装...
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>
【讨论】:
这就是答案。我不需要 Vuex Action 中的额外承诺。但是,对于我的特定用例,我还需要支持捕获传播。我已经更新了对我有用的解决方案。感谢您的帮助!【参考方案2】:最终的工作是像Void Ray 所说的那样删除额外的 Promise。但是,在我的特定用例中,我还需要支持错误传播。因此,以下操作包含我需要进行的修复。
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
);
,
;
【讨论】:
以上是关于返回承诺的 Vuex 操作永远不会解析或拒绝的主要内容,如果未能解决你的问题,请参考以下文章
承诺要么永远不会被调用,要么被拒绝(Parse JS SDK)
当用户选择“不再询问”并禁用地理定位时,React native `Geolocation.getCurrentPosition` 承诺将永远不会被解决/拒绝