Как дождаться исполнения саги, чтобы закончить в redux-саге? - PullRequest
0 голосов
/ 13 октября 2018

У меня есть следующий сценарий:

export function* addCircle(circleApi, { payload }) {
    try {
        const response = yield apply(
            circleApi,
            circleApi.addCircle,
            [payload]
        );

        if (response.error_type) {
           yield put(addCircleFailedAction(response.error));
        } else {
            yield put(addCircleSucceededAction(response));
        }
    } catch (err) {
        console.error(err);
    }
}

export function* addTender(tenderApi, { payload }) {
    try {
       // NOTE: I want this to finish before continuing with rest of saga below.
       yield call(addCircleAction(payload.circlePayload));

       // Rest of saga removed for brevity.
    } catch (err) {
        console.error(err);
    }
}

Итак, в основном addCircle выполняет вызов API, и в зависимости от его успеха я вызываю соответствующее избыточное действие.Теперь внутри другой саги я называю действие ответственным за сагу addCircle и хочу, чтобы оно завершило выполнение, прежде чем я продолжу с остальной сагой.Я пытался использовать call, но в основном он не ждет завершения саги addCircle.Есть ли способ ждать этого?Я звоню addCircle изнутри моих компонентов, и у меня не было необходимости ждать его, но в этом конкретном случае мне нужно вызвать его внутри саги, поэтому мне действительно нужно ждать, пока он завершит выполнение, изменит состояниеприложения, так что я могу использовать обновленное состояние в оставшейся части addTender саги.Есть идеи?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Если вы отправляете несколько действий, которые вызывают addRender, то нет никакой гарантии, что take (...) будет фактически ожидать действия, вызванного вызовом yield.

export function* addCircle(circleApi, { payload }) {
  try {
      const response = yield apply(
          circleApi,
          circleApi.addCircle,
          [payload]
      );

      if (response.error_type) {
         yield put(addCircleFailedAction(response.error));
         return response;
      } else {
          yield put(addCircleSucceededAction(response));
          return response;
      }
  } catch (err) {
      console.error(err);
      return {err};
  }
}

export function* addTender(tenderApi, { payload }) {
  try {
     //because addCircle saga is returning something you can re use it
     // in other sagas.
     const result = yield call(addCircle,circleAPI?,payload.circlePayload);
     //check for result.error_type here
     // Rest of saga removed for brevity.
  } catch (err) {
      console.error(err);
  }
}

Ваш код ипринятый ответ приведет к ошибке, потому что call не принимает объект действия в качестве первого аргумента (он принимает объект типа {context, fn}).

Отправка действия и затемпрослушивание другого действия, которое могло или не могло быть побочным эффектом действия, которое вы только что отправили, является плохим замыслом.Вы отправляете эти действия асинхронно, и нет никакой гарантии, что все они потребуют одинакового времени для выполнения или предоставят ожидаемый побочный эффект в том же порядке, в котором они были запущены.

0 голосов
/ 13 октября 2018

Согласно вашему фрагменту кода, ваша сага addCircle отправит создателей действий addCircleFailedAction или addCircleSucceededAction непосредственно перед завершением выполнения.Поэтому нам придется ждать этих действий в вашей саге addTender.

По сути, это то, что вы должны делать.Я просто угадываю ваши типы действий на основе имен создателей действий.

yield call(addCircleAction(payload.circlePayload));
yield take([ADD_CIRCLE_FAILED_ACTION, ADD_CIRCLE_SUCCEEDED_ACTION]);

// Rest of the saga

Хотя есть один крайний случай.Вы не отправляете никаких действий в блоке catch вашей саги addCircle.Возможно, вы можете отправить действие под названием addCircleExceptionAction внутри блока catch и дождаться его вместе с другими действиями, подобными этому:

yield take([ADD_CIRCLE_FAILED_ACTION, ADD_CIRCLE_SUCCEEDED_ACTION, ADD_CIRCLE_EXCEPTION_ACTION]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...