promise.race() 사용법 이해
다음 두 가지 옵션이 있는 것으로 알고 있습니다.
네, 저도 알아요promise.all()
그래요. 약속을 병렬로 실행하고, 그리고..then
둘 다 성공적으로 해결된 경우 값을 제공합니다.다음은 예입니다.
Promise.all([
$.ajax({ url: 'test1.php' }),
$.ajax({ url: 'test2.php' })
])
.then(([res1, res2]) => {
// Both requests resolved
})
.catch(error => {
// Something went wrong
});
하지만 나는 이해할 수 없습니다.promise.race()
정확하게 해야 하나요?다시 말해서, 그것을 사용하지 않는 것과 무엇이 다릅니까?다음과 같이 가정합니다.
$.ajax({
url: 'test1.php',
async: true,
success: function (data) {
// This request resolved
}
});
$.ajax({
url: 'test2.php',
async: true,
success: function (data) {
// This request resolved
}
});
봐요? 안 써봤어요.promise.race()
그리고 그것은 다음과 같이 행동합니다.promise.race()
어쨌든, 제가 정확히 언제 사용해야 하는지 보여줄 간단하고 깨끗한 예가 있나요?promise.race()
?
보다시피, 그race()
먼저 확인되거나 거부된 약속 인스턴스를 반환합니다.
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "two"
// Both resolve, but p2 is faster
});
사용할 장면의 경우 요청의 비용 시간을 제한할 수 있습니다.
var p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
])
p.then(response => console.log(response))
p.catch(error => console.log(error))
와 함께race()
당신은 단지 반환된 약속을 받기만 하면 됩니다, 당신은 그 약속들 중 어떤 것에 대해 신경 쓸 필요가 없습니다.race([])
처음에 돌아온 것은,
하지만, 그것 없이는.race
당신의 예와 마찬가지로, 당신은 어떤 것이 먼저 돌아올지, 그리고 콜백을 양쪽에서 부를지 신경 써야 합니다.success
콜백
요청 일괄 처리에 사용했습니다.장기 실행을 위해 수만 개의 레코드를 일괄 처리해야 했습니다.우리는 그것을 병행할 수 있지만, 보류 중인 요청의 수가 감당할 수 없게 되는 것을 원하지 않았습니다.
레이스를 통해 고정된 수의 병렬 약속을 실행하고 완료될 때마다 교체할 약속을 추가할 수 있습니다.
const _ = require('lodash')
async function batchRequests(options) {
let query = { offset: 0, limit: options.limit };
do {
batch = await model.findAll(query);
query.offset += options.limit;
if (batch.length) {
const promise = doLongRequestForBatch(batch).then(() => {
// Once complete, pop this promise from our array
// so that we know we can add another batch in its place
_.remove(promises, p => p === promise);
});
promises.push(promise);
// Once we hit our concurrency limit, wait for at least one promise to
// resolve before continuing to batch off requests
if (promises.length >= options.concurrentBatches) {
await Promise.race(promises);
}
}
} while (batch.length);
// Wait for remaining batches to finish
return Promise.all(promises);
}
batchRequests({ limit: 100, concurrentBatches: 5 });
타임아웃 시스템을 구축하기 위한 일부입니다.
- 요청/계산이 다른 채널에 의해 취소될 수 있습니다.
- 나중에 계속 사용하겠지만 지금은 상호 작용이 필요합니다.
두 번째 예를 들어, 충분한 속도로 들어오는 경우 실제 콘텐츠를 표시하지 않으면서 "즉시" 스피너를 표시할 수 있습니다.다음을 몇 번 실행해 보십시오. 최소한 일부 콘솔 메시지가 "즉각"으로 표시됩니다.이것은 일반적으로 UI에서 작업을 수행하기 위해 연결될 수 있습니다.
주목해야 할 핵심은 - 의 결과입니다.Promise.race
부작용보다 훨씬 덜 중요합니다(하지만, 이것은 코드 냄새입니다).
// 300 ms _feels_ "instant", and flickers are bad
function getUserInfo(user) {
return new Promise((resolve, reject) => {
// had it at 1500 to be more true-to-life, but 900 is better for testing
setTimeout(() => resolve("user data!"), Math.floor(900*Math.random()));
});
}
function showUserInfo(user) {
return getUserInfo().then(info => {
console.log("user info:", info);
return true;
});
}
function showSpinner() {
console.log("please wait...")
}
function timeout(delay, result) {
return new Promise(resolve => {
setTimeout(() => resolve(result), delay);
});
}
Promise.race([showUserInfo(), timeout(300)]).then(displayed => {
if (!displayed) showSpinner();
});
첫 번째 예:
function timeout(delay) {
let cancel;
const wait = new Promise(resolve => {
const timer = setTimeout(() => resolve(false), delay);
cancel = () => {
clearTimeout(timer);
resolve(true);
};
});
wait.cancel = cancel;
return wait;
}
function doWork() {
const workFactor = Math.floor(600*Math.random());
const work = timeout(workFactor);
const result = work.then(canceled => {
if (canceled)
console.log('Work canceled');
else
console.log('Work done in', workFactor, 'ms');
return !canceled;
});
result.cancel = work.cancel;
return result;
}
function attemptWork() {
const work = doWork();
return Promise.race([work, timeout(300)])
.then(done => {
if (!done)
work.cancel();
return (done ? 'Work complete!' : 'I gave up');
});
}
attemptWork().then(console.log);
이 사진을 보면 시간 초과가console.log
시간 초과가 처음 발생할 때는 실행되지 않습니다.테스트 편의를 위해 절반 정도는 실패/성공해야 합니다.
다음은 의 사용법을 이해하는 쉬운 예입니다.promise.race()
:
서버에서 데이터를 가져와야 하는데 데이터를 로드하는 데 시간이 너무 오래 걸리면(예: 15초) 오류를 표시하려고 합니다.
promise를 두 으로 호출합니다.첫두한 당은 신두 가 고 약 지 를 을 가 속 것 니 다 입 부 것 다 를 단 니 입 번 race ( ) 는 당 한 순 첫 두 아 번 의 는 째 요 고 신 째 이 스 약 청 지 , ▁you ▁promise ▁promises ▁with ( ) ( ▁a ▁call ▁request 당 race ▁two신setTimeout(() => resolve("ERROR"), 15000)
요약:.
Promise.race
JS는 약속(예: 약속)을 허용하는 내장 함수입니다.Array
) 의 주장으로서.그런 다음 이 함수는 반복 가능 영역에 전달된 약속 중 하나가 해결되거나 거부되는 즉시 비동기식으로 약속을 반환합니다.
예 1:
var promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('Promise-one'), 500);
});
var promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('Promise-two'), 100);
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster than promise 1
});
은 이예서는약배전열달다니됩이의속으로 됩니다.Promise.race
두 약속 모두 해결되지만 약속1은 더 빨리 해결됩니다.됩니다. 의 문자열입니다.'Promise-one'
.
예 2:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('succes'), 2000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => reject('err'), 1000);
});
Promise.race([promise1, promise2])
.then((value) => {
console.log(value);
}).catch((value) => {
console.log('error: ' + value);
});
이 두 번째 예에서 두 번째 약속은 첫 번째 약속이 해결할 수 있는 것보다 더 빨리 거부됩니다. 그므로러.Promise.race
합니다.'err'
그것은 Promise2가 거부한 값이었습니다.
이해해야 할 핵심은Promice.race
약속을 실행하고 해당 실행 가능한 약속에서 처음으로 해결되거나 거부된 약속을 기반으로 약속을 반환합니다(해당되는 약속 포함).resolve()
또는reject()
값)을 입력합니다.
다음의 해결 방법을 예로 들어 보겠습니다.Promise.race
아래와 같이
const race = (promises) => {
return new Promise((resolve, reject) => {
return promises.forEach(f => f.then(resolve).catch(reject));
})
};
를 볼 수 .race
함수는 모든 약속을 실행하지만 먼저 완료하는 사람은 래퍼로 해결/해제합니다.Promise
.
언급URL : https://stackoverflow.com/questions/46376432/understanding-promise-race-usage
'programing' 카테고리의 다른 글
모범 사례 - 문자열의 첫 번째 문자를 소문자로 변환 (0) | 2023.08.15 |
---|---|
JQuery 또는 JavaScript:앵커 태그 하이퍼링크를 클릭하는 동안 시프트 키를 눌렀는지 여부를 어떻게 확인합니까? (0) | 2023.08.15 |
하나의 요소에 여러 개의 데이터 바인딩 속성을 갖는 방법은 무엇입니까? (0) | 2023.08.10 |
하위 항목의 -include와 -filter 간의 차이 (0) | 2023.08.10 |
https://xxx.visualstudio.com/DefaultCollection/_git/project 에 대한 인증 실패 (0) | 2023.08.10 |