ES6 Javascript에서 생성기로 약속 취소

이전 블로그 게시물에서 ES6 Javascript의 생성기에 대한 기본 사항을 설명했습니다. 읽지 않았다면 여기에서 확인할 수 있습니다 👉

많은 분들이 제너레이터의 실제 사용 사례를 요청하셨기 때문에 제가 직면한 문제 중 하나를 보여드리겠습니다.

소개



그러나 문제를 설명하기 위해 우리가 작업 중인 Mews Navigator 제품에 대해 몇 마디 말해야 합니다.

The Navigator allows you to check-in online, securely storing your credit card details and giving you full control over the information that you want to share.



이제 앱을 통해 온라인 체크인을 하고 결제 단계를 진행한다고 상상해 보세요.

따라서 다음 버튼을 클릭하면 로더와 결제 카드 목록이 표시됩니다. 아주 간단하죠?



지불 경로 렌더링



실제로 내부는 좀 더 복잡합니다. 구성 요소를 렌더링하기 전에 해결해야 할 몇 가지 단계가 있습니다.

// Let's say user goes to this url:
// www.mews.li/navigator/check-in/payment/:reservationId

// 1. This will check if the user is signed in.
// If yes go render <Dashboard /> if not go to <SignIn />
authAction(); // async

// 2. We need to fetch the reservations
fetchReservations(); // async

// 3. We need to check if `reservationId` and
// route itself is valid (If all checks pass go to next one)
isReservationIdValid({ reservations, currentReservation }); // sync

// 4. Fetch paymentcards
fetchPaymentCards(); // async

// 5. Fetching hotel entitites
fetchHotels(); // async

// 6. Some of hotels uses PCI proxy vault, if it does,
// we need to initialize PCI proxy script.
doesHotelUsePciProxy({ hotels, hotelId }); // sync

// 7. Fetch and init the script
initPciProxy(); // async


구성 요소를 렌더링하기 전에 몇 가지 검사와 일부 API 가져오기가 있습니다.

The catch is that if any of these checks could fail and based on which checks to fail, we would redirect to a specific case.



그렇다면 외부 라이브러리를 사용하지 않고 이 문제를 해결하는 방법은 무엇일까요? 저번에 이거 보여줬던 거 기억나?

function* avengersGenerator() {
  yield "Hulk"; // Pausing the execution
  yield "Thor";
  yield "Iron man";
  return "Ultron"; // Exiting of finishing the generator
  yield "Spiderman";
}

const iterator = avengersGenerator();

iterator.next();


View source code in codesandbox
return 문을 살펴보십시오. 이렇게 하면 실행이 중지되고 return 문 뒤에 있는 모든 내용이 무시됩니다.

이를 통해 Promise를 반복하고 Promise Chain의 어느 곳에서나 취소할 수 있습니다.

개념의 증거



라우팅에서 이 사례를 해결하기 위해 사용 사례에 대해 충분히 일반적인 것을 만들어 봅시다. 요점은 다음과 같습니다.
  • 동기화 및 비동기 기능(API 호출)을 처리할 수 있습니다
  • .
  • 일부 검사가 실패하는 즉시 코드가 리디렉션을 반환했습니다.
  • 충분히 일반적이므로 다른 경로에도 재사용할 수 있습니다.

  • 그래서 코드 샌드박스를 열었고 이 해결책을 제시했습니다 👉 Codesandbox

    콘솔에서 볼 수 있듯이 여러 작업과 몇 가지 검사가 있습니다. 실패할 것으로 예상되는 검사와 나머지 코드가 실행되지 않는 부분을 이동할 수 있습니다.


    View the source code in codesandbox

    그리고 다음은 코드의 결제 단계 경로에 대한 구현 예입니다.

    function* paymentRouteGenerator() {
      yield authAction();
      yield fetchReservations();
      yield isReservationIdValid();
    
      yield fetchPaymentCards();
      yield fetchHotels();
      yield doesHotelUsePciProxy({ hotelId });
      yield initPciProxy();
    }
    
    const CHECK_IN_PAYMENT_ROUTE = {
      name: Route.CheckInPayment,
      path: "/:reservationId",
      action: resolveAction(
        generatorWrapper(paymentRouteGenerator),
        renderComponent(() => <CheckInPaymentStep />)
      )
    };
    


    생성기용 핸들러를 작성해야 했습니다. 이것은 magic가 발생하는 곳입니다. 댓글에서 아래의 모든 단계를 설명했습니다.

    const generatorWrapper = generator => context => {
      // 1. Creating an iterator
      const iterator = generator(context);
    
      // 3. This function except yielded as a argument
      const handle = yielded => {
        const handleWithRedirectCheck = route => {
          // 4. Here is where the magic happens, we check if there is a redirect, if yes,
          // it would redirect (cancel) and will not execute the rest of the generator
          if (get("redirect", route)) {
            return route;
          }
          // Otherwise continue
          return handle(iterator.next());
        };
        // Exit if we are at the end of the generator
        if (yielded.done) {
          return;
        }
    
        // Handling the async case if action/check is a promise
        if (isPromise(yielded.value)) {
          return yielded.value.then(handleWithRedirectCheck);
        }
        // If its not a promise, we can call handleWithRedirectCheck directly
        return handleWithRedirectCheck(yielded.value);
      };
    
      // 2. Handling the iterator
      return handle(iterator.next());
    };
    


    View the source code in codesandbox

    지금은 그냥 가지고 노는 것이므로 더 좋은 방법으로 이 문제를 해결하는 방법을 알고 있다면 반드시 알려주세요. 😉


    읽어 주셔서 감사합니다



    이 발전기 시리즈에 대해 어떻게 생각하는지 의견 섹션에서 알려주십시오. 당신이 그것을 사랑한다면, 당신은 무엇을 해야할지 압니다! 친구 및 동료와 공유하십시오.

    다음 게시물에서 몇 가지 주제를 다루기를 원하시면 여기 또는 트위터에서 저에게 DM을 보내거나 제안 사항이 있으면 아래에 댓글을 달아주세요.

    다음에 또 뵙고 계속 해킹하세요✌


    우리가 무엇을 만들고 있는지@ Mews systems 우리는 또한hiring devs 다른 위치에 있는 사람들을 살펴보십시오. 질문이 있으시면 DM 주세요.

    좋은 웹페이지 즐겨찾기