আপনি একটি কৌণিক প্রতিশ্রুতি ফিরে আসার আগে তা সমাধান করতে পারেন?


125

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

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        return $http.get('/someUrl', {id:id});
    }
}

এবং এটি এর মতো ব্যবহার করুন:

somethingService.getSomething(5).then(function(thing) {
    alert(thing);
});

সমস্যাটি হ'ল কলব্যাক পূর্ব নির্ধারিত প্রতিশ্রুতির জন্য কার্যকর করে না। এটি কি বৈধ কাজ? এই পরিস্থিতি পরিচালনা করার জন্য আরও ভাল উপায় আছে কি?


10
একটি সহজতর উপায় প্রথম ক্ষেত্রে রিটার্ন লিখতে হয় return $q.when(Cache[id])। যাইহোক, আপনি প্রতিটি বার নতুন প্রতিশ্রুতি তৈরি করার কারণে এটি প্রতিবার কাজ করা এবং কলব্যাক কল করা উচিত।
musically_ut


1
টি ককটেলের। আমার জীবনের এক ঘন্টা হারিয়ে গেল। আমি এটি ইউনিট পরীক্ষায় চেষ্টা করছিলাম এবং পরীক্ষাটি শেষ হওয়ার পরে প্রতিশ্রুতি পূর্ণ হয়েছিল এবং আমি এটি দেখছিলাম না। কোডটি না দিয়ে আমার পরীক্ষা নিয়ে সমস্যা।
ক্রেগ Celeste

নিশ্চিত হয়ে নিন যে আপনি $ স্কোপ call কল করেছেন $ প্রয়োগ করার সময় () পরীক্ষা করার সময় জিনিসগুলি সাথে সাথে সমাধান হওয়ার বিষয়টি নিশ্চিত করুন resolve
dtabuenc

আমি মনে করি এটির জন্য HTTP ব্যাকেন্ডেন্ড.ফ্লাশ অ্যাকাউন্ট রয়েছে তবে $ q নাও পারে। আমি এই পরীক্ষায় সুযোগ ব্যবহার করছি না। আমি সরাসরি পরিষেবাটি পরীক্ষা করছি, তবে এটি যেভাবেই হোক কাজ করতে পেরেছি, ধন্যবাদ।
ক্রেগ Celeste

উত্তর:


174

সংক্ষিপ্ত উত্তর: হ্যাঁ, আপনি কোনও কৌনিক জেএস প্রতিশ্রুতি ফিরে আসার আগেই এটি সমাধান করতে পারেন, এবং এটি আপনার প্রত্যাশা মতো আচরণ করবে।

থেকে জেবি Nizet এর Plunkr কিন্তু এবং আসলে সাইটে কি মূলত জিজ্ঞাসা করা হল প্রসঙ্গের মধ্যে কাজ রি-ফ্যাক্টর (সেবার অর্থাত একটি ফাংশন কল)।

পরিষেবার ভিতরে ...

function getSomething(id) {
    // There will always be a promise so always declare it.
    var deferred = $q.defer();
    if (Cache[id]) {
        // Resolve the deferred $q object before returning the promise
        deferred.resolve(Cache[id]); 
        return deferred.promise;
    } 
    // else- not in cache 
    $http.get('/someUrl', {id:id}).success(function(data){
        // Store your data or what ever.... 
        // Then resolve
        deferred.resolve(data);               
    }).error(function(data, status, headers, config) {
        deferred.reject("Error: request returned status " + status); 
    });
    return deferred.promise;

}

নিয়ামকের ভিতরে ....

somethingService.getSomething(5).then(    
    function(thing) {     // On success
        alert(thing);
    },
    function(message) {   // On failure
        alert(message);
    }
);

আমি আশা করি এটি কাউকে সাহায্য করবে আমি অন্যান্য উত্তর খুব পরিষ্কার খুঁজে পাইনি।


2
আমি কত খুশী আমি এই শব্দ দিয়ে বর্ণনা করতে পারছি না, আপনি আমাকে এতটা সময় রক্ষা করেছিলেন এইচ-কে!
রিলার

যদি http জিইটি ব্যর্থ হয়, প্রত্যাশিত প্রতিশ্রুতি এইভাবে প্রত্যাখ্যান করা হবে না।
lex82

5
সুতরাং এই পোস্টের জন্য টিএল; ডাঃ হ্যাঁ, আপনি কোনও প্রতিশ্রুতি ফিরিয়ে দেওয়ার আগে এটি সমাধান করতে পারেন, এবং এটি শর্ট সার্কিট হিসাবে লক্ষ্য হিসাবে তৈরি করা হবে।
রে

1
এই উত্তরটি ক্রিস কোওয়ালের প্রশ্নেও প্রযোজ্য যা অ্যাংুলারের প্রতিশ্রুতি ভিত্তিক।
কিথ

আমি আপনার উত্তরে একটি ত্রুটি-পরিচালনার উদাহরণ যুক্ত করেছি, আমি আশা করি এটি ঠিক আছে।
সাইমন ইস্ট

98

কীভাবে সহজেই কৌনিক 1.x এ পূর্ব নির্ধারিত প্রতিশ্রুতি ফিরিয়ে আনতে হবে

সমাধান প্রতিশ্রুতি:

return $q.when( someValue );    // angular 1.2+
return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6

প্রত্যাখাত প্রতিশ্রুতি:

return $q.reject( someValue );

1
কারখানার প্রয়োজন নেই, সেই সাহায্যকারী ফাংশনগুলি ইতিমধ্যে উপলব্ধ:{resolved: $q.when, rejected: $q.reject}
বার্গি

ওহে বার্গি, আপনার মূল্যবান অবদানের জন্য আপনাকে ধন্যবাদ। আমি আমার উত্তর অনুসারে সম্পাদনা করেছি।
আন্দ্রে মিখায়লোভ - লোলমাস

2
আমি মনে করি এই উত্তরটি নির্বাচন করা উচিত।
মোর্তেজা তৌরানী

@ এমরতেজাটি যদি এটি নির্বাচিত হয় তবে এটি আমাকে সোনার ব্যাজ দেয় না। ;)
আন্দ্রে মিখায়লোভ - লোলমাস

6

অ্যারে বা অবজেক্টে আমি যদি ডেটা ক্যাশে করতে চাই তবে আমি সাধারণত এটি কীভাবে করি তা এখানে

app.factory('DataService', function($q, $http) {
  var cache = {};
  var service= {       
    getData: function(id, callback) {
      var deffered = $q.defer();
      if (cache[id]) {         
        deffered.resolve(cache[id])
      } else {            
        $http.get('data.json').then(function(res) {
          cache[id] = res.data;              
          deffered.resolve(cache[id])
        })
      }
      return deffered.promise.then(callback)
    }
  }

  return service

})

DEMO


0

আপনি ক্যাশে উপাদানটি আরম্ভ করতে ভুলে গেছেন

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        Cache[id] = $http.get('/someUrl', {id:id});
        return Cache[id];
    }
}

দুঃখিত। সেটা সত্য. আমি প্রশ্নের স্পষ্টতার জন্য কোডটি সহজ করার চেষ্টা করছিলাম। তবুও, যদি এটি পূর্ব-সংশোধন করা প্রতিশ্রুতিতে যায় তবে মনে হয় না যে কলব্যাক কল করছে।
ক্রেগ Celeste

2
আমি মনে করি না যদি আপনি কোন প্রতিশ্রুতি দিয়ে কোন প্রতিশ্রুতিটি সমাধান করেন তবে অভ্যন্তরীণ প্রতিশ্রুতি সমতল হবে। এটি Cacheযখন কোনও বস্তু ক্যাশে থাকে এবং যখন এটি একই হয় না তখন উদ্দেশ্যযুক্ত বস্তুগুলির পরিবর্তে প্রতিশ্রুতি এবং ক্ষেত্রেগুলির জন্য রিটার্নের ধরণকে জনিত করে। এটি আরও সঠিক, আমি মনে করি:$http.get('/someUrl', {id: id}).then(function (response) { Cache[id] = response.data; return Cache[id]; });
musically_ut

0

আমি আমার উত্স থেকে ডেটা পেতে এমন কোনও কারখানা ব্যবহার করতে চাই।

.factory("SweetFactory", [ "$http", "$q", "$resource", function( $http, $q, $resource ) {
    return $resource("/sweet/app", {}, {
        "put": {
            method: "PUT",
            isArray: false
        },"get": {
            method: "GET",
            isArray: false
        }
    });
}]);

তারপরে আমার মডেলটিকে এখানে সেবার মতো প্রকাশ করুন

 .service("SweetService",  [ "$q", "$filter",  "$log", "SweetFactory",
    function ($q, $filter, $log, SweetFactory) {

        var service = this;

        //Object that may be exposed by a controller if desired update using get and put methods provided
        service.stuff={
            //all kinds of stuff
        };

        service.listOfStuff = [
            {value:"", text:"Please Select"},
            {value:"stuff", text:"stuff"}];

        service.getStuff = function () {

            var deferred = $q.defer();

          var promise = SweetFactory.get().$promise.then(
                function (response) {
                    if (response.response.result.code !== "COOL_BABY") {
                        deferred.reject(response);
                    } else {
                        deferred.resolve(response);
                        console.log("stuff is got", service.alerts);
                        return deferred.promise;
                    }

                }
            ).catch(
                function (error) {
                    deferred.reject(error);
                    console.log("failed to get stuff");
                }
            );

            promise.then(function(response){
                //...do some stuff to sett your stuff maybe fancy it up
                service.stuff.formattedStuff = $filter('stuffFormatter')(service.stuff);

            });


            return service.stuff;
        };


        service.putStuff = function () {
            console.log("putting stuff eh", service.stuff);

            //maybe do stuff to your stuff

            AlertsFactory.put(service.stuff).$promise.then(function (response) {
                console.log("yep yep", response.response.code);
                service.getStuff();
            }).catch(function (errorData) {
                alert("Failed to update stuff" + errorData.response.code);
            });

        };

    }]);

তারপরে আমার কন্ট্রোলাররা এটি অন্তর্ভুক্ত করতে পারে এবং প্রকাশ করতে পারে বা যা পড়ে তা ঠিক তার প্রসঙ্গে ঠিক ইনজেকশনের পরিষেবা উল্লেখ করে করতে পারে।

ঠিক আছে কাজ মনে হচ্ছে। তবে আমি কৌণিক নতুন ধরণের। * পরিষ্কার করার জন্য বেশিরভাগ ক্ষেত্রে রেখে যাওয়া ত্রুটি পরিচালনা করা


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