لذلك لدي موقف حيث لدي سلاسل الوعد متعددة بطول غير معروف. أريد تشغيل بعض الإجراءات عند معالجة جميع السلاسل. هل هذا ممكن؟ هنا مثال:
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()
للوعود واحد ، اثنان ، وثلاثة والتي سيتم حلها في وقت عشوائي. ثم أضيف الوعود على طرف واحد وثلاثة. أريد حل 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
:
ثم (successCallback ، errorCallback ، notifyCallback) - بغض النظر عن متى تم أو سيتم حل الوعد أو رفضه ، ثم يقوم باستدعاء أحد عمليات الاستعادة للنجاح أو الخطأ بشكل متزامن بمجرد توفر النتيجة. يتم استدعاء عمليات الاسترجاعات مع وسيطة واحدة : سبب النتيجة أو الرفض.
$ q.all (عود)
يجمع بين الوعود المتعددة في وعد واحد يتم حله عندما يتم حل جميع وعود المدخلات.
يمكن أن يكون promises
param مجموعة من الوعود.
حول bind()
، مزيد من المعلومات هنا: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
يمكنك استخدام "انتظار" في "وظيفة غير متزامن" .
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");