Как ничего не делать, когда 1 из обещаний отклонено

#javascript #reactjs #redux #promise

#javascript #reactjs #redux #обещание

Вопрос:

Здравствуйте, я использую Promise для обновления товара и добавления продажи.
Чего я хочу, так это когда одно из условий не выполняется. Все обновления и добавления sale не произойдут.

Вот код, который я использую

 const onFinish = (values) => {

const UpdateItem = new Promise((resolve, reject) => {
        // Update the item
        resolve(this.props.updateItem(this.props.item.items, index));
        console.log('items updated')
      })

      const AddSale = new Promise((resolve,reject) => {
        // Add To Sale
        resolve(this.props.addSale(newSale));
        console.log('sales added')
      })

      const reloadPage = new Promise((resolve,reject) => {
        reject(new Error('rejected'))
      })

      Promise.all([UpdateItem, AddSale, reloadPage]).then((values) => {
        console.log(values)
      }).catch(error => { 
        console.error(error.message)
      });
}
  

Что происходит сейчас, так это. При запуске функции. Элемент обновляется. осуществляется продажа. после этого в последнем состоянии обещание отклоняется.

Даже если оно отклонено, изменения в товаре и продаже уже внесены. Я не хочу, чтобы это происходило. Я использую redux для обновления элементов.

Вот this.props.updateItem и this.props.addSale код. Они находятся внутри другого файла

 export const addItem = (item) => (dispatch, getState) => {
  // will hit reducer
  Axios.post("/api/items", item, tokenConfig(getState))
    .then((res) => {
      dispatch({
        type: ADD_ITEM,
        // res.data is new item
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch(returnErrors(err.response.data, err.response.status));
    });
};

export const addSale = (sale) => (dispatch, getState) => {
    // will hit reducer
    // console.log(sale)
    Axios.post("/api/sales", sale, tokenConfig(getState))
      .then((res) => {
        dispatch({
          type: ADD_SALE,
          // res.data is new sale
          payload: res.data,
        });
      })
      .catch((err) => {
        dispatch(returnErrors(err.response.data, err.response.status));
      });
  };
  

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

1. Чао, единственный способ, который я вижу, — это операция отката при сбое Pormise.all. Что-то вроде: Promise.all(...).catch(error => Axios.post("/api/deleteItem", item...) и то же самое для продаж.

2. Используйте Promise.allSettled() вместо Promise.all() , если хотите знать, когда будут выполнены все обещания, даже если некоторые из них отклонены.

3. Нормально ли UpdateItem, AddSale, reloadPage запускать параллельно или их нужно запускать последовательно один за другим? В данный момент ваш код выполняет их параллельно, поэтому AddSale не ожидает UpdateItem и reloadPage не ожидает ни одного из других.

4. Чао @jfriend00, я не знаю Promise.allSettled, но могу я задать вам несколько вопросов? Предположим, что addSale post вставляет значение в db. Затем reloadPage появляется и отклоняет обещание. Как Promise.allSettled может откатить addSale сообщение? примечание: мой вопрос не ироничный. Это просто для понимания того, как работает Promise.allSettled.

5. Пожалуйста, прочтите страницу, на которую я уже ссылался Promise.allSettled() . Там все в порядке. И, похоже, вы все равно не хотите запускать эти операции параллельно, а скорее хотите упорядочить их, а затем разветвлять свою логику в зависимости от того, выполняется ли какой-либо отдельный шаг успешно или неудачно. В этом случае вам не следует использовать Promise.all() or Promise.allSettled() . Вы должны написать код, который выполняет одну операцию, проверяет, была ли она успешной, а затем разветвляется в вашем коде на основе результата.