Сбой обещания в действии Vuex при ошибке API - PullRequest
0 голосов
/ 29 мая 2019

Это, вероятно, проблема использования неправильного шаблона для достижения того, что мне нужно, поэтому либо ответ о том, какой шаблон (и что это за шаблон) я должен использовать, либо что решило бы мой текущий шаблон, было бы очень полезно!

У меня есть сценарий использования, когда мне нужно подождать от 1 до многих вызовов API для успешного завершения, прежде чем направить пользователя на другую страницу / представление ... Вот что я делаю:

// Vuex action
[POST_NEW_INVOICE_UPDATE]: ({ commit }, update) => {
    return apiEndpoints
      .postNewInvoiceUpdate(update)
      .then(() => {
        app.$Progress.finish()
        app.$Toastr.success('Invoice flagged')
      })
      .catch((error) => {
        console.error(error)
        app.$Progress.fail()
        app.$Toastr.error('There was an issue submitting your request', 'Request error')
      })
},
// In component
flag () {
    // ... simplifying for TLDR
    const promises = []
    flagSelections.forEach(selection => {
        // ... simplifying for TLDR
        promises.push(this.$store.dispatch('POST_NEW_INVOICE_UPDATE', parameters))
    })

    Promise.all(promises)
        .then(() => {
            // Route to next invoice in previous search, if search exists
            // ... simplifying for TLDR
        })
        .catch((error) => {
            console.error(error)
        })
},

Я создаю массив действия POST_NEW_INVOICE_UPDATE и вызываю Promise.all для этого массива.Я хочу, чтобы цепочка .then разорвалась, когда .catch в действии обнаружила ошибку, потому что я не хочу направлять своих пользователей до тех пор, пока API не будут успешными.

Мне кажется, я прочитал в MDN, что .then продолжает цепочку, даже если обнаружена ошибка, но мне, очевидно, нужно что-то, чтобы предотвратить маршрутизацию моего пользователя до того, как все API-интерфейсы будут успешными.

Я думаю, что яЯ просто использую тупой, самостоятельно созданный шаблон и неправильно использую действия Vuex, поэтому любая помощь в правильном направлении будет принята с благодарностью!

РЕДАКТИРОВАТЬ: я забыл что-то важное!Если я беру код из действия и помещаю его в promises.push вместо отправки, код работает по мере необходимости, но я ненавижу нарушать шаблон использования Vuex для одного варианта использования.

1 Ответ

1 голос
/ 29 мая 2019

Во-первых, я бы не использовал Vuex исключительно для вызовов API. Цель Vuex - управлять глобальным состоянием, и я вижу, что вы даже не используете commit для его изменения вообще. Вы можете абстрагировать свой API в свои собственные объекты или функции без необходимости использования Vuex. Но возможно, вы просто урезали код и на самом деле звоните commit, поэтому я придерживаюсь этого предположения.

Кроме того, Vuex запрещает совершать звонки типа app.$Progress.fail(). Vuex не должен ничего знать о ваших компонентах или пользовательском интерфейсе, его единственная задача - управлять глобальным состоянием.

Вот как бы я это структурировал:

async flag() {
  const promises = [];

  flagSelections.forEach(selection => {
    promises.push(postNewInvoiceUpdate(parameters));
  });

  try {
    await Promise.all(promises);
    app.$Progress.finish();
    app.$Toastr.success('Invoice flagged');
  } catch (e) {
    console.error(error);
    app.$Progress.fail();
    app.$Toastr.error(
      'There was an issue submitting your request',
      'Request error'
    );
  }
},

Если какое-либо из Обещаний не выполнится, будет выполнен код в блоке catch. Promise.all означает все Обещания должны выполняться, а не только некоторые из них. И я бы просто import postNewInvoiceUpdate из отдельного модуля. Для этого не нужно использовать Vuex.

...