How to make axios synchronous

cochae·2022년 10월 31일
0

error

목록 보기
4/5

axios를 동기 처리 하기 위해선 async/await 키워드를 사용하면 된다

  • function 앞에 async 키워드를 추가하면 두 가지 효과가 있다.
  1. 함수는 언제나 프라미스를 반환한다.
  2. 함수 안에서 await를 사용할 수 있다.
  • 프라미스 앞에 await 키워드를 붙이면 자바스크립트는 프라미스가 처리될 때까지 대기한다. 처리가 완료되면 다음 동작이 진행한다.

🤔 만약 호출뿐 아니라 응답값도 동기적으로 받아야 한다면?

작성 중인 코드에서 api test 항목을 배열로 가져와 map 메소드로 순차적으로 호출했다.
호출은 순차적으로 했지만 응답는 처리 속도가 빠른 순서대로 받을 수 있었다.
인증 여부 확인, 유저 정보 확인과 같은 get 메소드가 인증 로그아웃인 delete 메소드보다 느리게 응답했다.

export const apiTest = async (req: Request, res: Response) => {
 const { ConnInfo, Services } = req.body;
 logger.info(`Test : 총 ${Services.length}`);
 
 // 토큰 발급
 let apiToken = await getToken(ConnInfo);
 ConnInfo.apiToken = apiToken;
 
 // 테스트 진행
 Services &&
   Services.map(async (service: Service, index: number) => {
     logger.info(`ServiceName : ${service.ServiceName}`);

    const testAxios = axios.create({
      httpsAgent: new https.Agent({
        rejectUnauthorized: false,
      }),
      baseURL: ConnInfo.baseUrl,
      method: service.ReqMethod,
    });

    // 필요한 데이터 파싱
    service = JSON.parse(Sqrl.render(JSON.stringify(service), ConnInfo));
    const { ReqURL, ReqBodyTmp, ReqHeaderTmps, ResBodyType } = service;

    // axios call
    const res = await testAxios
      .request({ url: ReqURL, data: ReqBodyTmp, headers: ReqHeaderTmps })
      .then((res) => {
        service.RespBodyTmp = res.data;
        logger.info(`${index} ${service.ServiceName} res.data : ${res.data}`);
        return res.data;
      })
      .catch((err) => {
        logger.error(err);
      });
  }
};

아직은 로그인, 로그아웃 정도의 test를 진행하기 때문에 결과값을 동기적으로 받지 않아도 괜찮지만,
다른 test 케이스의 경우 이전 호출의 응답값을 사용해 다음 호출에 사용해야 했기 때문에 응답도 동기적으로 처리가 필요했다.

👉 map 메소드를 for..of문으로 수정하니 응답값도 동기적으로 받아 올 수 있었다.

// 테스트 진행
  for (let service of Services) {
    logger.info(`ServiceName : ${service.ServiceName}`);
    ...
  }

이렇게 코드를 수정하면 모든 요청을 동기적으로 수행하기 때문에 작업시간은 길다.
하지만 순차적으로 test를 진행해야 하는 경우면 for...of문이 적합하다.

그럼 왜 저 둘은 다르게 작동하는가? 내용 추가 필요.


0개의 댓글