[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));
Promise
생성자에 전달 된 함수 는 비동기가 아니므로 linter에 오류가 표시되지 않습니다.- 모든 비동기 함수는를 사용하여 순차적으로 호출 할 수 있습니다
await
. - 비동기 작업의 결과를 검증하기 위해 사용자 지정 오류를 추가 할 수 있습니다.
- 결국 오류가 잘 잡 힙니다.
단점은 비록 당신이 퍼팅을 기억해야한다는 것입니다 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 객체를 적용했기 때문에 충분합니다.