여러 기능을 기다리겠다고 약속하고 실패한 기능을 다시 시도하십시오.
12360 단어 typescriptjavascriptnode
1개의 URL에서 여러 비동기 요청이 있으면 해당 서버에 과부하가 걸릴 수 있습니다. 이러한 일이 발생하면 서버가 다시 시작되고 몇 초(분 또는 그 이상) 동안 오프라인 상태가 되고 모든 요청이 실패하게 됩니다.
모든 웹사이트가 API를 제공하는 것은 아니기 때문에 많은 웹사이트를 크롤링해야 하는 경우가 있습니다. 한 번에 많은 대형 웹사이트를 크롤링하려면 꽤 오랜 시간이 걸릴 수 있습니다. 웹 사이트에 연결해야 하는 시간이 많을수록 요청 시간 초과가 발생할 가능성이 높아집니다. 특히 응용 프로그램의 대역폭이 제한된 경우. 이로 인해 요청 시간이 초과될 수 있습니다.
개발자가 수동으로 요청을 다시 시작하지 않고 애플리케이션이 위의 모든 작업을 자동으로 수행해야 하는 경우 더 복잡합니다.
여기 내 솔루션이 있습니다. 3가지 기능만 필요합니다(4번째 기능은 선택 사항임).
Promise.all()
를 넣고 모든 약속이 실행된 후 원하는 것을 넣습니다. axios.get()
함수를 넣어 타사로부터 요청을 받고 요청이 성공하면 JSON을 반환하고 요청이 실패하면 URL(문자열)을 반환합니다. setTimeout()
를 넣습니다. (이 기능은 다음 요청을 지연하려는 경우 선택 사항입니다). 액시오스 함수
예를 들어, 이 간단한 api 을 사용할 것입니다. JSON으로 예상되는 결과:
{
"test": "one",
"hello": "world"
}
이 API로 인해 오류(내부 서버)가 발생한다고 가정하고 throw 대신 URL을 반환합니다.
const axiosFunc: any = (async (url: string) => {
return await axios.get(url)
.then(response => response.data)
.catch(e => url);
});
모든 기능을 약속
Promise.all()
약속 배열을 허용합니다. 다음과 같이 작성하는 대신:Promise.all([axiosFunc(url1),axiosFunc(url2),...]);
다음과 같이 작성할 수 있습니다.
const urls = [url1,url2,...];
Promise.all(urls.map(url => this.axiosFunc(url));
예상 결과는 Axios 함수의 결과 배열, 즉 json 객체(api의 결과) 또는 문자열(url)입니다. 단순
if..else
및 .some()
를 사용하여 결과에 문자열이 있는지 여부를 확인합니다. 문자열이 있으면 .filter()
를 사용하여 유형별로 결과를 분할합니다.if(data.some(val => typeof val == 'string')) {
/** filter failed one by checking its type and execute again */
const failedReq = data.filter(val => typeof val == 'string');
this.requestAgain(failedReq);
/** filter success one by checking its type and save its result to db */
const successReq = data.filter(val => typeof val !== 'string');
this.saveResult(successReq);
} else {
this.saveResult(data);
}
문자열 1(실패한 1)은
this.requestAgain()
로 이동합니다. 이 게시물의 뒷부분에서 이 기능에 대해 알아보겠습니다. 그리고 문자열이 아닌 것(성공한 것)은 this.saveResult()
로 이동합니다. 이 기능에서 성공적인 결과의 데이터는 데이터베이스 또는 캐시 또는 기타 데이터 저장 방법에 저장됩니다.다음은 이 함수의 전체 코드입니다.
const promiseAllFunc: void = ((urls: string[]) => {
return await Promise.all(urls.map(url => this.axiosFunc(url))
.then(data => {
if(data.some(val => typeof val == 'string')) {
/** filter failed one by checking its type and execute again */
const failedReq = data.filter(val => typeof val == 'string');
this.requestAgain(failedReq);
/** filter success one by checking its type and save its result to db */
const successReq = data.filter(val => typeof val !== 'string');
this.saveResult(successReq);
} else {
this.saveResult(data);
}
})
});
주요 기능
url 배열(타사 API)을 매개변수로 사용하여 위에서 Promise All 함수를 호출합니다.
const main: any = (() => {
let dummyUrls = [
'http://echo.jsontest.com/hello/world/test/one',
'http://echo.jsontest.com/hello/world/test/two',
'http://echo.jsontest.com/hello/world/test/three'
];
return this.promiseAllFunc(dummyUrls);
});
지연 기능
이 기능은 선택 사항입니다. 다음 요청을 지연시키려면
setTimeout()
로 추가 기능을 작성할 수 있습니다. 다음은 다음 요청에 대해 10초 지연이 있는 예입니다.const requestAgain: any = ((urls: string[]) => {
setTimeout(() => {
this.promiseAllFunc(urls);
}, 10000);
});
이 방법은 내 모든 문제를 해결합니다. 자동으로 실행됩니다(Cronjob 사용). 실패한 요청 재시도(Cronjob을 사용하여 지연 기능을 수정할 수도 있음).
그렇군요, 감사합니다 :)
의견 섹션에 의견을 자유롭게 추가하십시오. 이것은 내 첫 번째 게시물입니다. 여기 저기에 문법 실수가 있을 수 있지만 (또는 그 이상 :D ), 여전히 이해할 수 있다고 생각합니다.
Reference
이 문제에 관하여(여러 기능을 기다리겠다고 약속하고 실패한 기능을 다시 시도하십시오.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wbwb/promise-wait-for-multiple-functions-and-retry-some-failed-function-3aba텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)