Действие Vuex, возвращающее обещание jQuery, не работает, .fail не является функцией

#jquery #vue.js #vuejs2 #vuex #jquery-deferred

#jquery #vue.js #vuejs2 #vuex #jquery-отложенный

Вопрос:

У меня есть действие vuex, подобное этому

 myAction() {
    const deferred = $.Deferred();
    setTimeout(() => deferred.resolve(), 3000);
    return deferred.promise();
}
  

в моем компоненте vue

 myMethod() {
    this.myAction().fail(() => ...do something...);
}
  

выдает ошибку:

Неперехваченная ошибка типа: это.MyAction(…).fail не является функцией

Код работал нормально, но проблема появилась после того, как я обновил свои модули npm / vue-cli / webpack и т. Д. Другой момент, если я изменю .fail на .catch then, он будет работать нормально. Но вопрос в том, почему .fail не работает?

Комментарии:

1. То, что вы описываете, произойдет, если myAction не удастся явно вернуть обещание jQuery (вместо этого оно вернет неявное обещание оболочки). Вы тестировали упрощенный пример выше и все равно получили ошибку? Просто интересно, достаточно ли ваше фактическое действие отличается от примера.

2. это именно то, что я пробовал, это. MyAction().catch(…) работает, но это. MyAction().fail не

3. Я использую vuex 3.4.0

Ответ №1:

Начиная с Vuex 3.4.0, действия всегда возвращают собственное обещание. В прошлых версиях Vuex только проверял, вернуло ли действие объект, который можно изменить, т. Е. Что-Либо со .then свойством. Если нет, то возвращаемое значение действия преобразуется в новое обещание. Но если это так, он просто вернул объект без его упаковки, предполагая, что это было обещание. Начиная с версии 3.4.0, Vuex переносит даже изменяемые объекты.

Таким образом, в прошлом $.Deferred обещание могло ускользнуть, потому что у него есть .then метод, который возвращает $ объект promise с .fail помощью метода. Но теперь оно оборачивается собственным обещанием.


registerAction

Если вы проверите источник Vuex, вы увидите, что registerAction он не изменился с 3.3.0 на 3.4.0. Это где возвращаемые значения, не подлежащие замене, завернуты в обещания. Это не изменилось:

 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) {
  ...
})
  

Но теперь он всегда возвращает оболочку обещания:

 return new Promise(function (resolve, reject) {
  result.then(function (res) {  // Doesn't return the inner promise either
    ...
  })
})
  

И оболочка также не утруждает себя возвратом внутреннего результата. Похоже, Vuex решил нормализовать возвращаемое значение actions, чтобы оно гарантированно было встроенным обещанием.

Комментарии:

1. Вот скрипка , которую я использовал при тестировании некоторых вещей