it-swarm.asia

انتظر جميع الوعود لحلها

لذلك لدي موقف حيث لدي سلاسل الوعد متعددة بطول غير معروف. أريد تشغيل بعض الإجراءات عند معالجة جميع السلاسل. هل هذا ممكن؟ هنا مثال:

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 

هل هناك طريقة لانتظار السلاسل لحلها؟

104
jensengar

أريد أن يحل الكل عندما يتم حل جميع السلاسل.

بالتأكيد ، ثم مرر وعد كل سلسلة في 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");
});
154
Bergi

الإجابة المقبولة صحيحة. أود تقديم مثال لتوضيحه قليلاً لأولئك الذين ليسوا على دراية بـ 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

16
Hieu
0
Nikola Yovchev

يمكنك استخدام "انتظار" في "وظيفة غير متزامن" .

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");
0
Flavouski