Angularjs $ q.all


105

আমি Angularjs এ in q.all প্রয়োগ করেছি, তবে আমি কোডটি কাজ করতে পারি না। আমার কোডটি এখানে:

UploadService.uploadQuestion = function(questions){

        var promises = [];

        for(var i = 0 ; i < questions.length ; i++){

            var deffered  = $q.defer();
            var question  = questions[i]; 

            $http({

                url   : 'upload/question',
                method: 'POST',
                data  : question
            }).
            success(function(data){
                deffered.resolve(data);
            }).
            error(function(error){
                deffered.reject();
            });

            promises.push(deffered.promise);
        }

        return $q.all(promises);
    }

এবং এখানে আমার নিয়ামক যা পরিষেবাগুলিকে কল করে:

uploadService.uploadQuestion(questions).then(function(datas){

   //the datas can not be retrieved although the server has responded    
}, 
function(errors){ 
   //errors can not be retrieved also

})

আমি মনে করি আমার পরিষেবাতে $ q.all সেট আপ করতে কিছু সমস্যা আছে।


1
কি আচরণ দেখছেন? এটি কি আপনার মধ্যে কল then(datas)? pushpromises.push(deffered);
এটির

@ themyth92 আপনি কি আমার সমাধান চেষ্টা করেছেন?
ইলান ফ্রুমার

আমি চেষ্টা করেছি এবং উভয় পদ্ধতিই আমার ক্ষেত্রে কাজ করে। তবে আমি @ ল্লান ফ্রুমারকে সঠিক উত্তর হিসাবে তৈরি করব। সত্যিই আপনাকে উভয় ধন্যবাদ।
themyth92

1
আপনি কেন বিদ্যমান প্রতিশ্রুতি প্রতিজ্ঞা করছেন? $ এইচটিপি ইতিমধ্যে একটি প্রতিশ্রুতি দেয়। $ Q.defer এর ব্যবহার অতিমাত্রায় হয়।
পিট আলভিন

1
এটি deferredনয় deffered:)
ক্রিস্টোফ রুসি

উত্তর:


225

জাভাস্ক্রিপ্টে block-level scopesকেবল নেই function-level scopes:

জাভা স্ক্রিপ্ট স্কোপিং এবং উত্তোলন সম্পর্কে এই নিবন্ধটি পড়ুন ।

আমি কীভাবে আপনার কোডটি ডিবাগ করেছি তা দেখুন:

var deferred = $q.defer();
deferred.count = i;

console.log(deferred.count); // 0,1,2,3,4,5 --< all deferred objects

// some code

.success(function(data){
   console.log(deferred.count); // 5,5,5,5,5,5 --< only the last deferred object
   deferred.resolve(data);
})
  • আপনি যখন var deferred= $q.defer();লুপের জন্য লিখেন এটি ফাংশনের শীর্ষে উত্তোলন করা হয়, এর অর্থ জাভাস্ক্রিপ্টটি এই পরিবর্তনশীলটি এর বাইরে ফাংশন স্কোপে ঘোষণা করে for loop
  • প্রতিটি লুপের সাথে, শেষ মুলতুবিটি পূর্ববর্তীটিকে ওভাররাইড করে that অবজেক্টের রেফারেন্স সংরক্ষণ করার জন্য কোনও ব্লক-স্তরের সুযোগ নেই।
  • যখন অ্যাসিঙ্ক্রোনাস কলব্যাকস (সাফল্য / ত্রুটি) আহ্বান করা হয়, তারা কেবল শেষ মুলতুবি বস্তুটি উল্লেখ করে এবং কেবল এটি সমাধান হয়ে যায়, তাই। Q.all কখনই সমাধান হয় না কারণ এটি এখনও অন্যান্য পিছিয়ে থাকা বস্তুর জন্য অপেক্ষা করে।
  • আপনার যা প্রয়োজন তা হ'ল আপনার পুনরাবৃত্তি হওয়া প্রতিটি আইটেমের জন্য একটি বেনামী ফাংশন তৈরি করা।
  • যেহেতু ফাংশনগুলির স্কোপ থাকে না, closure scopeফাংশন সম্পাদন হওয়ার পরেও পিছিয়ে দেওয়া বস্তুর উল্লেখটি সংরক্ষণ করা হয় in
  • যেমন # ডিএফএসকিউ মন্তব্য করেছে: $ http নিজেই একটি প্রতিশ্রুতি ফেরত দেওয়ার কারণে ম্যানুয়ালি নতুন একটি পিছিত বস্তু তৈরি করার দরকার নেই।

এর সাথে সমাধান angular.forEach:

এখানে একটি ডেমো প্লঙ্কার: http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p= পূর্বরূপ

UploadService.uploadQuestion = function(questions){

    var promises = [];

    angular.forEach(questions , function(question) {

        var promise = $http({
            url   : 'upload/question',
            method: 'POST',
            data  : question
        });

        promises.push(promise);

    });

    return $q.all(promises);
}

আমার প্রিয় উপায়টি হ'ল Array#map:

এখানে একটি ডেমো প্লঙ্কার: http://plnkr.co/edit/KYeTWUyxJR4MLU77svw9?p= পূর্বরূপ দেখুন

UploadService.uploadQuestion = function(questions){

    var promises = questions.map(function(question) {

        return $http({
            url   : 'upload/question',
            method: 'POST',
            data  : question
        });

    });

    return $q.all(promises);
}

14
ভাল উত্তর. একটি সংযোজন: def এইচটিপি নিজেই প্রতিশ্রুতি দেয় বলে নতুন স্থগিতের নির্মাণের প্রয়োজন নেই। সুতরাং এটি আরও খাটো হতে পারে: plnkr.co/edit/V3gh7Roez8WWl4NKKrqM?p= পূর্বরূপ
dfsq

"যখন আপনি var ਮੁਲিত্য = $ q.defer () লিখেন; লুপের জন্য এটি ফাংশনের শীর্ষে উত্তোলিত হয়" " আমি এই অংশটি বুঝতে পারি না, আপনি কি এর পিছনের কারণটি ব্যাখ্যা করতে পারেন?
themyth92

আমি জানি, আমি আসলে একই কাজ করতাম।
dfsq

4
mapপ্রতিশ্রুতির অ্যারে তৈরি করতে ব্যবহার পছন্দ করুন Love খুব সাধারণ এবং সংক্ষিপ্ত।
ড্রামবেগ

1
এটি লক্ষণীয় হওয়া উচিত যে ঘোষণাটি উত্তোলন করা হয় তবে অ্যাসাইনমেন্টটি যেখানে থাকে সেখানেই থাকে। এছাড়াও, এখন 'লেট' বিবৃতি দিয়ে ব্লক-স্তরের স্কোপিং রয়েছে। দেখুন developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
স্পেন্সর

36

$ এইচটিপি একটি প্রতিশ্রুতিও, আপনি এটিকে আরও সহজ করে তুলতে পারেন:

return $q.all(tasks.map(function(d){
        return $http.post('upload/tasks',d).then(someProcessCallback, onErrorCallback);
    }));

2
হ্যাঁ, গৃহীত উত্তরটি কেবলমাত্র অ্যান্টি-প্যাটার্নগুলির সংশ্লেষ।
রোমের -1888

আমি মনে করি আপনি এই .then()ধারাটি ছাড়তে পারেন কারণ ওপি তার নিয়ন্ত্রকের মধ্যে যা করতে চায় তবে নীতিটি সম্পূর্ণ সঠিক।
রোমের -1888

2
অবশ্যই আপনি তখনকার ধারাটি বাদ দিতে পারেন, আপনি সমস্ত HTTP অনুরোধগুলি লগ করতে চাইলে আমি এটিকে যুক্ত করেছিলাম, সমস্ত সার্ভারের ব্যতিক্রমগুলি পরিচালনা করতে আমি সর্বদা সেগুলি যুক্ত করে এবং একটি গ্লোবাল অনারার কলব্যাক ব্যবহার করি।
জেরকোটিন

1
আপনি যা করতে পারেন @Zerkotin throwA থেকে .thenউভয় হ্যান্ডেল পরে করার জন্য এবং এটি এক্সপোজ $exceptionHandler, যা আপনি যে কষ্ট এবং একটি বিশ্বব্যাপী সংরক্ষণ করা উচিত।
বেনজামিন গ্রুইনবাউম

খুশী হলাম। এটি মূলত গৃহীত উত্তরের শেষ সমাধান / উদাহরণের মতো একই পন্থা।
নিকো বেলিক

12

সমস্যাটি মনে হচ্ছে আপনি নিজেরাই যে প্রতিশ্রুতি যুক্ত করবেন তা আপনি deffered.promiseযখন defferedযুক্ত করছেন:

এটিকে পরিবর্তন করার চেষ্টা করুন promises.push(deffered);যাতে আপনি অ্যারেটিতে আবদ্ধ প্রতিশ্রুতিটি যুক্ত না করেন।

 UploadService.uploadQuestion = function(questions){

            var promises = [];

            for(var i = 0 ; i < questions.length ; i++){

                var deffered  = $q.defer();
                var question  = questions[i]; 

                $http({

                    url   : 'upload/question',
                    method: 'POST',
                    data  : question
                }).
                success(function(data){
                    deffered.resolve(data);
                }).
                error(function(error){
                    deffered.reject();
                });

                promises.push(deffered);
            }

            return $q.all(promises);
        }

এটি কেবল ডিফার্ড অবজেক্টগুলির একটি অ্যারের ফিরিয়ে দেয়, আমি এটি পরীক্ষা করেছিলাম।
ইলান ফ্রুমার

তিনি কী বলছেন তা আমি জানি না, কেবল কনসোল যা বলে, আপনি দেখতে পাচ্ছেন এটি কাজ করছে না: plnkr.co/edit/J1ErNncNsclf3aU86D7Z?p= পূর্বরূপ
ইলান ফ্রুমার

4
এছাড়াও ডকুমেন্টেশনটি পরিষ্কারভাবে বলেছে যে $q.allপ্রতিশ্রুতিগুলি পিছিয়ে দেওয়া বস্তুগুলি নয়। ওপি-র আসল সমস্যাটি
স্কোপিংয়ের

ইলান, অবতরণকারী deferবস্তুর জন্য ধন্যবাদ এবং promises। আপনি আমার all()সমস্যাটিও ঠিক করেছেন।
রস রজার্স

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