返回 jQuery 承诺的 Vuex 动作不起作用,.fail 不是函数
Posted
技术标签:
【中文标题】返回 jQuery 承诺的 Vuex 动作不起作用,.fail 不是函数【英文标题】:Vuex action returning jQuery promise doesn't work, .fail is not a function 【发布时间】:2021-02-25 03:38:24 【问题描述】:我有一个像这样的 vuex 动作
myAction()
const deferred = $.Deferred();
setTimeout(() => deferred.resolve(), 3000);
return deferred.promise();
在我的 vue 组件中
myMethod()
this.myAction().fail(() => ...do something...);
抛出错误:
未捕获的类型错误:this.myAction(...).fail 不是函数
代码运行良好,但是一旦我更新了我的 npm 模块/vue-cli/webpack 等,问题就出现了。另一点是,如果我将 .fail
更改为 .catch
,那么它运行正常。但问题是为什么.fail
不起作用?
【问题讨论】:
如果myAction
未能显式返回 jQuery 承诺(它将返回隐式包装承诺),您所描述的将会发生。您是否测试了上面的简化示例并且仍然得到错误?只是想知道您的实际操作是否与示例足够不同。
这正是我尝试过的,this.myAction().catch(...) 有效,但 this.myAction().fail 无效
我正在使用 vuex 3.4.0
【参考方案1】:
从 Vuex 3.4.0 开始,动作总是返回一个原生承诺。在过去的版本中,Vuex 只检查一个操作是否返回一个 thennable 对象,即任何具有.then
属性的对象。如果不是,它将操作返回值包装在一个新的承诺中。但如果是这样,它只是简单地返回对象而不包装它,假设它是一个承诺。从 3.4.0 开始,Vuex 甚至包装了 thennnable 对象。
所以在过去,$.Deferred
承诺能够溜过,因为它有一个 .then
方法,该方法返回一个带有 .fail
方法的 $
承诺对象。但现在它被封装在原生 Promise 中。
注册操作
如果您检查 Vuex 源代码,您会看到 registerAction
没有从 3.3.0 更改为 3.4.0。这是 non-thennable 返回值被包装在 Promise 中的地方。它没有改变:
function registerAction (store, type, handler, local)
...
if (!isPromise(res))
res = Promise.resolve(res);
...
store.dispatch.prototype
但store.dispatch.prototype
确实发生了变化。它过去只返回.then
方法:
return result.then(function (res)
...
)
但现在它总是返回一个 promise 包装器:
return new Promise(function (resolve, reject)
result.then(function (res) // Doesn't return the inner promise either
...
)
)
而且包装器也不会费心返回内部结果。看来 Vuex 已经决定规范化操作的返回值,以保证它是一个原生的 Promise。
【讨论】:
这是我在测试一些东西时使用的fiddle以上是关于返回 jQuery 承诺的 Vuex 动作不起作用,.fail 不是函数的主要内容,如果未能解决你的问题,请参考以下文章
Redux-Thunk - 异步动作创建者承诺和链接不起作用