Beginning with Vuex 3.4.0, actions always return a native promise. In past versions, Vuex only checked whether an action returned a thennable object, i.e. anything with .then
property. If not, it wrapped the action return value in a new promise. But if so, it simply returned the object without wrapping it, assuming it was a promise. Starting with 3.4.0, Vuex wraps even thennable objects.
So in the past, the $.Deferred
promise was able to slip by, because it has a .then
method which returns a $
promise object with a .fail
method. But now it gets wrapped in a native promise.
registerAction
If you inspect the Vuex source, you see that registerAction
didn't change from 3.3.0 to 3.4.0. This is where non-thennable return values are wrapped in promises. It hasn't changed:
function registerAction (store, type, handler, local) {
...
if (!isPromise(res)) {
res = Promise.resolve(res);
}
...
}
store.dispatch.prototype
But store.dispatch.prototype
did change. It used to just return the .then
method:
return result.then(function (res) {
...
})
But now it always returns a promise wrapper:
return new Promise(function (resolve, reject) {
result.then(function (res) { // Doesn't return the inner promise either
...
})
})
And the wrapper doesn't bother to return the inner result either. It seems Vuex has decided to normalize the return value of actions so that it's guaranteed to be a native promise.
myAction
failed to explicitly return the jQuery promise (it would return an implicit wrapper promise instead). Did you test the simplified example above and still get the error? Just wondering if your actual action is different enough from the example.