সমস্ত প্রতিশ্রুতি সমাধানের জন্য অপেক্ষা করুন


107

সুতরাং আমার এমন এক পরিস্থিতি রয়েছে যেখানে আমার অজানা দৈর্ঘ্যের একাধিক প্রতিশ্রুতি রয়েছে। সমস্ত 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()প্রতিশ্রুতিগুলির জন্য একটি, দুটি এবং তিনটির জন্য একটি সেট আপ করেছি যা এলোমেলো সময়ে সমাধান হয়ে যাবে। আমি তখন এক এবং তিনটি প্রান্তে প্রতিশ্রুতি যুক্ত করি। আমি চাই allযখন সমস্ত চেইনগুলি সমাধান হয়ে গেছে তখন সমাধান করা উচিত। আমি এই কোডটি চালানোর সময় এখানে আউটপুট দেওয়া হবে:

one done 
one doneChained
two done
three done
ALL PROMISES RESOLVED
three doneChained
three doneChainedChained 

চেইনগুলি সমাধান করার জন্য অপেক্ষা করার কোনও উপায় আছে কি?

উত্তর:


161

আমি চাই যখন সমস্ত চেইনগুলি সমাধান হয়ে গেছে তখন সকলেরই সমাধান করা উচিত।

অবশ্যই, তবে প্রতিটি 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");
});

2
আমার সবচেয়ে খারাপ ভয় নিশ্চিত করার জন্য ধন্যবাদ। সর্বশেষ প্রতিশ্রুতিটি লোল পেতে এখন আমাকে একটি উপায় নিয়ে আসতে হবে।
জেনেসঙ্গার

তাতে সমস্যা কী? আপনার চেইনগুলি গতিশীলভাবে নির্মিত হয়েছে?
বার্গি

ঠিক আমার সমস্যা। আমি গতিশীলভাবে একটি প্রতিশ্রুতি শৃঙ্খলা তৈরি করার চেষ্টা করছি তখন চেইন (গুলি) সম্পূর্ণ হয়ে গেলে আমি কিছু করতে চাই।
jensengar

আপনি কি আমাদের আপনার কোডটি প্রদর্শন করতে পারেন (সম্ভবত কোনও নতুন প্রশ্ন জিজ্ঞাসা করতে পারেন)? মৃত্যুর পরে শৃঙ্খলে সংযুক্ত আইটেমগুলি রয়েছে কি না Q.all- অন্যথায় এটি তুচ্ছ হওয়া উচিত?
বার্গি

আমি আপনাকে কোডটি দেখাতে চাই ... তবে আমি এখনও এটি লেখা শেষ করি নি, তবে আমি এটি ব্যাখ্যা করার জন্য যথাসাধ্য চেষ্টা করব। আমার কাছে "ক্রিয়া" করার একটি তালিকা রয়েছে যা করা দরকার done এই ক্রিয়াকলাপগুলির সাথে তাদের সাথে সংযুক্ত কয়েকটি স্তরের উপ-ক্রিয়া থাকতে পারে। সমস্ত ক্রিয়াকলাপ এবং তাদের সাবজেক্ট সম্পূর্ণ হয়ে গেলে আমি কিছু করতে সক্ষম হতে চাই। সম্ভবত একাধিক $q.allগুলি থাকবে, তবে আমি একবার সমাধান প্রক্রিয়াটি শুরু করার পরে, কোনও নতুন ক্রিয়া / প্রতিশ্রুতিবদ্ধ হবে না।
জেনেসেঙ্গার

16

গৃহীত উত্তর সঠিক। যারা এর সাথে পরিচিত নন তাদেরকে এটি একটু বিস্তৃত করার জন্য আমি উদাহরণ দিতে চাই promise

উদাহরণ:

আমার উদাহরণে, সামগ্রীটি রেন্ডার করার আগে যদি আমার কাছে পাওয়া যায় তবে বিভিন্ন মিরর url সহ ট্যাগগুলির srcবৈশিষ্ট্যগুলি প্রতিস্থাপন করতে হবে img

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.
);

ব্যাখ্যা:

অ্যাঙ্গুলারজেএস ডক্স থেকে :

thenপদ্ধতি:

তারপরে (সাফল্যক্যালব্যাক, ত্রুটি কলব্যাক, বিজ্ঞপ্তি কলব্যাক) - প্রতিশ্রুতি কখন ছিল বা সমাধান করা হবে বা প্রত্যাখ্যাত হবে তা নির্বিশেষে, ফলাফল পাওয়ার সাথে সাথেই সাফল্য বা ত্রুটি কলব্যাকগুলির মধ্যে একটিটিকে কল হিসাবে সংযুক্তি হিসাবে কল করে। কলব্যাকগুলি একক যুক্তি দিয়ে ডাকা হয় : ফলাফল বা প্রত্যাখার কারণ।

$ Q.all (প্রতিশ্রুতি)

একক প্রতিশ্রুতিতে একাধিক প্রতিশ্রুতি যুক্ত করে যা সমাধান করা হয় যখন সমস্ত ইনপুট প্রতিশ্রুতিগুলি সমাধান করা হয়।

পরম promisesপ্রতিশ্রুতির একটি বিন্যাস হতে পারে।

সম্পর্কে bind(), এখানে আরও তথ্য: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / ফাংশন / বাইন্ড


thenপদ্ধতি $q.allফিরে প্রতিশ্রুতি একটি অ্যারের প্রদান করা হয়, তাই আপনি যা করতে পারেন লুপ যে অ্যারের এবং কল thenঅ্যারের মধ্যে প্রতিটি আইটেমের, যেমন কলিং উল্টোদিকে উপর thenযখন আপনি প্রতিশ্রুতি যোগ promise_array
নিক

4

সম্প্রতি এই সমস্যা কিন্তু ব্যবহার promises.Solved এর অজানা নম্বর দিয়ে 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;
}

এটি jQuery.map () নয় বরং অ্যারে.প্রোটোটাইপ.ম্যাপ () ( বিকাশকারী.মোজিলা.আর.ইন / ডকস / ওয়েব / জাভা স্ক্রিপ্ট / রেফারেন্স /… ) তবে এই পদ্ধতির কাজ করে।
Anastasia

0

একটি উপায় আছে. $q.all(...

আপনি নীচের জিনিসপত্র পরীক্ষা করতে পারেন:

http://jsfiddle.net/ThomasBurleson/QqKuk/

http://denisonluz.com/blog/index.php/2013/10/06/angularjs-returning-multiple-promises-at-once-with-q-all/


এটির জন্য আমার চেইনের দৈর্ঘ্যটি সঠিক হওয়া দরকার কি? মানে আমার যদি দৈর্ঘ্য 10 এর প্রতিশ্রুতি থাকে তবে আমাকে $q.all([p1.then(..).then(...).then(...).then(...) ...]);সঠিকভাবে করতে হবে ?
jensengar

0

আপনি একটি "async ফাংশন" এ "অপেক্ষা" ব্যবহার করতে পারেন ।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.