그래서 길이를 알 수없는 약속 체인이 여러 개있는 상황이 있습니다. 모든 CHAINS가 처리되었을 때 몇 가지 작업을 실행하고 싶습니다. 그게 가능할까요? 다음은 예입니다.
app.controller('MainCtrl', function($scope, $q, $timeout) {
var one = $q.defer();
var two = $q.defer();
var three = $q.defer();
var all = $q.all([one.promise, two.promise, three.promise]);
all.then(allSuccess);
function success(data) {
console.log(data);
return data + "Chained";
}
function allSuccess(){
console.log("ALL PROMISES RESOLVED")
}
one.promise.then(success).then(success);
two.promise.then(success);
three.promise.then(success).then(success).then(success);
$timeout(function () {
one.resolve("one done");
}, Math.random() * 1000);
$timeout(function () {
two.resolve("two done");
}, Math.random() * 1000);
$timeout(function () {
three.resolve("three done");
}, Math.random() * 1000);
});
이 예 $q.all()
에서는 임의의 시간에 해결 될 약속 1, 2, 3에 대한 a 를 설정했습니다 . 그런 다음 1과 3의 끝에 약속을 추가합니다. all
모든 체인이 해결되면 해결 하기 를 원합니다 . 이 코드를 실행할 때의 출력은 다음과 같습니다.
one done
one doneChained
two done
three done
ALL PROMISES RESOLVED
three doneChained
three doneChainedChained
체인이 해결 될 때까지 기다리는 방법이 있습니까?
답변
모든 체인이 해결되면 모든 것이 해결되기를 바랍니다.
물론, 각 체인의 약속을 all()
초기 약속 대신에 전달하십시오 .
$q.all([one.promise, two.promise, three.promise]).then(function() {
console.log("ALL INITIAL PROMISES RESOLVED");
});
var onechain = one.promise.then(success).then(success),
twochain = two.promise.then(success),
threechain = three.promise.then(success).then(success).then(success);
$q.all([onechain, twochain, threechain]).then(function() {
console.log("ALL PROMISES RESOLVED");
});
답변
허용 대답은 올바른 것입니다. 에 익숙하지 않은 사람들에게 좀 더 자세히 설명하는 예제를 제공하고 싶습니다 promise
.
예:
내 예에서는 콘텐츠를 렌더링하기 전에 사용 가능한 경우 태그 의 src
속성을 img
다른 미러 URL 로 교체해야 합니다.
var img_tags = content.querySelectorAll('img');
function checkMirrorAvailability(url) {
// blah blah
return promise;
}
function changeSrc(success, y, response) {
if (success === true) {
img_tags[y].setAttribute('src', response.mirror_url);
}
else {
console.log('No mirrors for: ' + img_tags[y].getAttribute('src'));
}
}
var promise_array = [];
for (var y = 0; y < img_tags.length; y++) {
var img_src = img_tags[y].getAttribute('src');
promise_array.push(
checkMirrorAvailability(img_src)
.then(
// a callback function only accept ONE argument.
// Here, we use `.bind` to pass additional arguments to the
// callback function (changeSrc).
// successCallback
changeSrc.bind(null, true, y),
// errorCallback
changeSrc.bind(null, false, y)
)
);
}
$q.all(promise_array)
.then(
function() {
console.log('all promises have returned with either success or failure!');
render(content);
}
// We don't need an errorCallback function here, because above we handled
// all errors.
);
설명:
AngularJS 문서에서 :
then
방법 :
then (successCallback, errorCallback, notifyCallback) – 약속이 언제 해결되거나 거부되었는지에 관계없이 결과가 제공되는 즉시 성공 또는 오류 콜백 중 하나를 비동기 적으로 호출합니다. 콜백은 단일 인수 ( 결과 또는 거부 이유) 로 호출됩니다 .
$ q.all (약속)
여러 약속을 모든 입력 약속이 해결 될 때 해결되는 단일 약속으로 결합합니다.
promises
PARAM는 약속의 배열 일 수있다.
정보 bind()
, 자세한 정보 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
답변
최근 에이 문제가 있었지만 알 수없는 수의 promise가 있습니다 .jQuery.map ()을 사용하여 해결했습니다 .
function methodThatChainsPromises(args) {
//var args = [
// 'myArg1',
// 'myArg2',
// 'myArg3',
//];
var deferred = $q.defer();
var chain = args.map(methodThatTakeArgAndReturnsPromise);
$q.all(chain)
.then(function () {
$log.debug('All promises have been resolved.');
deferred.resolve();
})
.catch(function () {
$log.debug('One or more promises failed.');
deferred.reject();
});
return deferred.promise;
}
답변
답변
“async function”에서 “await”를 사용할 수 있습니다 .
app.controller('MainCtrl', async function($scope, $q, $timeout) {
...
var all = await $q.all([one.promise, two.promise, three.promise]);
...
}
참고 : 비 비동기 함수에서 비동기 함수를 호출하고 올바른 결과를 얻을 수 있는지 100 % 확신하지 못합니다.
그것은 이것이 웹 사이트에서 사용되지 않을 것이라고 말했습니다. 하지만 부하 테스트 / 통합 테스트의 경우 …
예제 코드 :
async function waitForIt(printMe) {
console.log(printMe);
console.log("..."+await req());
console.log("Legendary!")
}
function req() {
var promise = new Promise(resolve => {
setTimeout(() => {
resolve("DARY!");
}, 2000);
});
return promise;
}
waitForIt("Legen-Wait For It");