[javascript] new Promise () 생성자 내부에서 async / await를 사용하는 것이 안티 패턴입니까?

async.eachLimit번에 최대 작업 수를 제어 하는 기능을 사용하고 있습니다.

const { eachLimit } = require("async");

function myFunction() {
 return new Promise(async (resolve, reject) => {
   eachLimit((await getAsyncArray), 500, (item, callback) => {
     // do other things that use native promises.
   }, (error) => {
     if (error) return reject(error);
     // resolve here passing the next value.
   });
 });
}

보시다시피 myFunction함수의 두 번째 콜백 내부의 값에 액세스 할 수 없기 때문에 함수를 비동기로 선언 할 수 없습니다 eachLimit.



답변

promise 생성자 실행기 함수 내에서 promise를 효과적으로 사용하고 있으므로 Promise 생성자 anti-pattern 입니다.

코드는 모든 오류를 안전하게 전파하지 않는 주요 위험의 좋은 예입니다. 거기에 이유 읽기 .

또한 async/ await를 사용하면 동일한 함정을 훨씬 더 놀랍게 만들 수 있습니다. 비교:

let p = new Promise(resolve => {
  ""(); // TypeError
  resolve();
});

(async () => {
  await p;
})().catch(e => console.log("Caught: " + e)); // Catches it.

순진한 (잘못된) async동등 물 :

let p = new Promise(async resolve => {
  ""(); // TypeError
  resolve();
});

(async () => {
  await p;
})().catch(e => console.log("Caught: " + e)); // Doesn't catch it!

브라우저의 웹 콘솔에서 마지막 콘솔을 찾으십시오.

첫 번째 는 Promise 생성자 실행기 함수의 즉각적인 예외가 새로 생성 된 promise를 편리하게 거부 하기 때문에 작동 합니다..then 사용자가 직접 수행).

두 번째는 async함수의 즉각적인 예외 함수 자체에서 반환 한 암시 적 약속을 거부 하기 때문에 작동하지 않습니다.async 입니다.

프라 미스 생성자 실행 함수의 반환 값이 사용되지 않았기 때문에 그것은 나쁜 소식입니다!

귀하의 코드

다음 myFunction과 같이 정의 할 수없는 이유는 없습니다 async.

async function myFunction() {
  let array = await getAsyncArray();
  return new Promise((resolve, reject) => {
    eachLimit(array, 500, (item, callback) => {
      // do other things that use native promises.
    }, error => {
      if (error) return reject(error);
      // resolve here passing the next value.
    });
  });
}

왜 오래된 동시성 제어 라이브러리를 사용 await합니까?


답변

나는 위에 주어진 답변에 동의하며, 때로는 약속 내부에 비동기를 갖는 것이 더 깔끔합니다. 특히 약속을 반환하는 여러 작업을 연결하고 then().then()지옥을 피하려는 경우 더욱 그렇습니다 . 그 상황에서 다음과 같은 것을 사용하는 것을 고려할 것입니다.

const operation1 = Promise.resolve(5)
const operation2 = Promise.resolve(15)
const publishResult = () => Promise.reject(`Can't publish`)

let p = new Promise((resolve, reject) => {
  (async () => {
    try {
      const op1 = await operation1;
      const op2 = await operation2;

      if (op2 == null) {
         throw new Error('Validation error');
      }

      const res = op1 + op2;
      const result = await publishResult(res);
      resolve(result)
    } catch (err) {
      reject(err)
    }
  })()
});

(async () => {
  await p;
})().catch(e => console.log("Caught: " + e));
  1. Promise생성자에 전달 된 함수 는 비동기가 아니므로 linter에 오류가 표시되지 않습니다.
  2. 모든 비동기 함수는를 사용하여 순차적으로 호출 할 수 있습니다 await.
  3. 비동기 작업의 결과를 검증하기 위해 사용자 지정 오류를 추가 할 수 있습니다.
  4. 결국 오류가 잘 잡 힙니다.

단점은 비록 당신이 퍼팅을 기억해야한다는 것입니다 try/catch및에 부착 reject.


답변

static getPosts(){
    return new Promise( (resolve, reject) =>{
        try {
            const res =  axios.get(url);
            const data = res.data;
            resolve(
                data.map(post => ({
                    ...post,
                    createdAt: new Date(post.createdAt)
                }))
            )
        } catch (err) {
            reject(err);
        }
    })
}

await를 제거하면 async가이 문제를 해결합니다. Promise 객체를 적용했기 때문에 충분합니다.


답변