체인의정석

블록체인 트랜잭션 데이터 처리할 때 Promise.all 과 Promise.resolve 를 같이 써서 속도 최적화 시키기 본문

개발/backend

블록체인 트랜잭션 데이터 처리할 때 Promise.all 과 Promise.resolve 를 같이 써서 속도 최적화 시키기

체인의정석 2023. 2. 23. 16:07
728x90
반응형

블록체인의 연산 처리를 빠르게 하기 위해서는 적재적소에 동기처리와 비동기 처리를 섞어서 잘 써주는 것이 중요하다.

 

이 경우 Promise.all과 Promise.resolve를 잘 써주면 해결이 가능하다.

 

Promise.all

Promise.all은 내부의 함수를 비동기화 하여 모두 호출시켜준다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

 

Promise.all() - JavaScript | MDN

Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫

developer.mozilla.org

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// Expected output: Array [3, 42, "foo"]

그리고 그 안에는 온갖 종류들이 다 들어갈 수 있다.

 

그 중에서는 Promise.resolve나 new Promise와 같은 동기 처리가 된 함수와 비동기 처리된 함수가 모두 포함된다.

 

또한 중간에 하나라도 에러가 날 경우 전체 취소가 된다.

 

예외처리도 한번만 해주면 된다.

 

이에 따라서 트랜잭션 관련된 부분은 Promise.resolve로 리턴 값을 주고 배열을 하나 만들어서 해당 배열을 리턴해준다면?

처리는 병렬로 해버리고 뎔과 값은 동기화 시켜서 받을 수 있다.

 

아래와 같이 하면 결과값을 모아서 한번에 처리할 수 있다.

  async function txReciptExtract(tx) {
    const getTxRecipt = await web3.eth.getTransactionReceipt(tx);
    const sender = getTxRecipt.from;
	.
    .
    .
    const result = {
		sender,
        ,
        ,
        ...
    };
    return Promise.resolve(result);
  }

async function batchAsyncTxs(transactions) {
    const asyncArray = [];
    try {
      for (tx in transactions) {
        asyncArray.push(txReciptExtract(tx));
      }
      const resultArr = await Promise.all(asyncArray);
      console.log('resultArr >>', resultArr);
      const results = resultArr.reduce((acc, val) => acc.concat(val), []);
      return Promise.resolve(results);
    } catch (error) {
      return Promise.resolve(error);
    }
  }

코드를 보면 Promis.resolve로 Promise 형태의 리턴 값을 만들어 준후 

txReceiptEtxtract에 await를 안걸어 주었다.

이건 해당 객체 자체를 넣어버린 것이다.

 

여기에 await을 걸어주면 동기 처리가 되어서 실행이 되고

비동기로 병렬처리 후에 결과값에 대해서만 동기처리를 하게 되는 것이다.

 

 

한마디로 명령이 들어오면 해당 명령을 병렬로 처리하고 결과 값은 모든 명령이 다 끝나면 보내주게 되기 때문에 순서가 안꼬이고 효율적으로 처리가 되는 것이다.

 

블록당 트랜잭션이 폭발적으로 늘어나는 순간이 있기 때문이 이처럼 병렬처리 로직을 넣어주어야 빠른 처리가 가능하다.

Promise.race

그리고 재밌는 함수를 하나 발견했는데 race를 쓰면 가장 빨리 처리된애 하나만 결과가 온다고 한다.

나중에 응용할 때 사용 가능할것 같다.

 

참고사항

내부적으로 복잡한 로직을 처리할 때 

Promise.all 을 통해서 리턴 받은 값

또는 이미 Promis.resolve를 가져오는 부분은

 

함수의 최상단에만 await를 걸어주면 되며

최상단의 리턴 값까지 가는 중간 함수들은 이미 Promise 객체로 되어 있는 부분들에 대해서는 더이상 Promise.resolve를 사용하지 않아도 된다.

 

 

 

728x90
반응형
Comments