সাফল্য / ত্রুটি / অবশেষে / অ্যাঙ্গুলারজেএস-এ প্রতিশ্রুতি সহ ধরা


112

আমি $httpAngularJs এ ব্যবহার করছি , এবং ফেরত প্রতিশ্রুতি কীভাবে ব্যবহার করতে হবে এবং ত্রুটিগুলি পরিচালনা করতে হবে সে বিষয়ে আমি নিশ্চিত নই।

আমার এই কোডটি রয়েছে:

$http
    .get(url)
    .success(function(data) {
        // Handle data
    })
    .error(function(data, status) {
        // Handle HTTP error
    })
    .finally(function() {
        // Execute logic independent of success/error
    })
    .catch(function(error) {
        // Catch and handle exceptions from success/error/finally functions
    });

এটি করার জন্য এটি কি ভাল উপায়, না কোনও সহজ উপায় আছে?

উত্তর:


103

প্রতিশ্রুতিগুলি বিবৃতিগুলির উপর একটি বিমূর্ততা যা আমাদেরকে সিঙ্ক্রোনাসলি অ্যাসিক্রোনাস কোডের সাথে প্রকাশ করতে দেয়। তারা এককালীন কার্য সম্পাদনের প্রতিনিধিত্ব করে।

এগুলি ব্যতিক্রম হ্যান্ডলিং সরবরাহ করে, সাধারণ কোডের মতো, আপনি কোনও প্রতিশ্রুতি থেকে ফিরে আসতে পারেন বা আপনি নিক্ষেপ করতে পারেন।

আপনি সিঙ্ক্রোনাস কোডে যা চান তা হ'ল:

try{
  try{
      var res = $http.getSync("url");
      res = someProcessingOf(res);
  } catch (e) {
      console.log("Got an error!",e);
      throw e; // rethrow to not marked as handled
  }
  // do more stuff with res
} catch (e){
     // handle errors in processing or in error.
}

প্রদত্ত সংস্করণটি খুব অনুরূপ:

$http.get("url").
then(someProcessingOf).
catch(function(e){
   console.log("got an error in initial processing",e);
   throw e; // rethrow to not marked as handled, 
            // in $q it's better to `return $q.reject(e)` here
}).then(function(res){
    // do more stuff
}).catch(function(e){
    // handle errors in processing or in error.
});

4
আপনি কিভাবে ব্যবহার করবেন success(), error()এবং finally()সঙ্গে মিলিত catch()? বা আমার কী ব্যবহার করতে হবেthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);
জোয়েল

3
@ জোয়েল সাধারণত, আপনি কখনও ব্যবহার করতে চান না successএবং error(পছন্দ করুন .thenএবং .catchপরিবর্তে, আপনি আমার কোডটির মতো উপরের ব্যবহার এসি errorFunctionথেকে বাদ দিতে পারেন (এবং হওয়া উচিত) )। .thencatch
বেনিয়ামিন গ্রুইনবাউম

@ বেনজামিন গ্রুয়েনবাউম আপনি কীভাবে এড়াতে পরামর্শ দিচ্ছেন success/ আপনি এটিকে বিস্তারিত বলতে পারবেন error? এছাড়াও আমার গ্রহণটি যখন দেখায় তা অদ্ভুতভাবে চালায় .catch(তাই আমি ["catch"](আপাতত ব্যবহার করি । আমি কীভাবে গ্রহণ করতে পারি?
গিজমো

কৌণিকের $ HT মডিউলটির $ q লাইব্রেরির প্রয়োগটি .থান এবং .ক্যাচের পরিবর্তে .success এবং .error ব্যবহার করে। তবে আমার পরীক্ষায় আমি। Http প্রতিশ্রুতির সমস্ত বৈশিষ্ট্য অ্যাক্সেস করতে পারি যখন। Zd333 এর উত্তরও দেখুন।
স্টিভ কে

3
@SirBenBenji $ কুই নেই .successএবং .error, $ HTTP একটি $ কুই প্রতিশ্রুতি ফেরৎ যোগে এর successএবং errorহ্যান্ডেলার - যাইহোক, এই হ্যান্ডলার শৃঙ্খল না এবং সাধারণত যদি / যখন সম্ভব এড়িয়ে চলা উচিত। সাধারণভাবে - আপনার যদি প্রশ্ন থাকে তবে তাদের কোনও নতুন প্রশ্ন হিসাবে জিজ্ঞাসা করা ভাল, কোনও পুরানো বিষয়ে মন্তব্য হিসাবে নয়।
বেনিয়ামিন গ্রুইনবাউম

43

ব্যবহার successএবং errorপদ্ধতি সম্পর্কে ভুলে যান ।

উভয় পদ্ধতি কৌনিক 1.4 এ অবমূল্যায়ন করা হয়েছে। মূলত, অবমূল্যায়নের পিছনে কারণ হ'ল তারা শৃঙ্খল-বান্ধব নয় , তাই কথা বলার জন্য।

নিম্নলিখিত উদাহরণে, আমি প্রকট আমি কি বলতে চাচ্ছি চেষ্টা করব successএবং errorহচ্ছে না chainable বান্ধব । মনে করুন আমরা এমন একটি এপিআই কল করি যা কোনও ব্যবহারকারীর সাথে কোনও ঠিকানা দিয়ে ফেরত দেয়:

ব্যবহারকারী অবজেক্ট:

{name: 'Igor', address: 'San Francisco'}

এপিআইতে কল করুন:

$http.get('/user')
    .success(function (user) {
        return user.address;   <---  
    })                            |  // you might expect that 'obj' is equal to the
    .then(function (obj) {   ------  // address of the user, but it is NOT

        console.log(obj); // -> {name: 'Igor', address: 'San Francisco'}
    });
};

কি হলো?

কারণ successএবং errorআসতে মূল প্রতিশ্রুতি , অর্থাত্ দ্বারা ফিরে এক $http.get, বস্তুর কলব্যাক প্রেরণ thenপুরো হয় ব্যবহারকারী বস্তু, পূর্ববর্তী একই ইনপুট বলতে হয় যে successকলব্যাক।

আমরা যদি দু'জনকে বেঁধে রাখি then, তবে এটির বিভ্রান্তি কম হত:

$http.get('/user')
    .then(function (user) {
        return user.address;  
    })
    .then(function (obj) {  
        console.log(obj); // -> 'San Francisco'
    });
};

1
এটিও লক্ষণীয় successএবং errorএটি কেবলমাত্র তাত্ক্ষণিক$http কলটিতে ফিরে আসা (প্রোটোটাইপ নয়) যুক্ত করা হয়, সুতরাং আপনি যদি তাদের মধ্যে অন্য প্রতিশ্রুতি পদ্ধতিতে কল করেন (যেমন, আপনি সাধারণত return $http.get(url)বেস লাইব্রেরিতে আবৃত কল করেন তবে পরে কোনও স্পিনারকে টগল করার সিদ্ধান্ত নেন লাইব্রেরির সাথে কল করুন return $http.get(url).finally(...)) তারপরে আপনার আর সেই সুবিধাদির পদ্ধতি নেই।
ড্রাজস

35

আমি মনে করি পূর্ববর্তী উত্তরগুলি সঠিক, তবে এখানে আরেকটি উদাহরণ রয়েছে (কেবলমাত্র একটি ফাই, সাফল্য () এবং ত্রুটি () অ্যাঙ্গুলারজেএস মূল পৃষ্ঠা অনুসারে অবচয় করা হয়েছে :

$http
    .get('http://someendpoint/maybe/returns/JSON')
    .then(function(response) {
        return response.data;
    }).catch(function(e) {
        console.log('Error: ', e);
        throw e;
    }).finally(function() {
        console.log('This finally block');
    });

3
পরিশেষে আমার জ্ঞানটি, প্রতিক্রিয়া ফিরিয়ে দেয় না।
ডিপ্লোসরাস

11

আপনি কী ধরণের গ্র্যানুলারিটি খুঁজছেন? আপনি সাধারণত এর মাধ্যমে পেতে পারেন:

$http.get(url).then(
  //success function
  function(results) {
    //do something w/results.data
  },
  //error function
  function(err) {
    //handle error
  }
);

আমি খুঁজে পেয়েছি যে একাধিক প্রতিশ্রুতি দেওয়ার সময় "অবশেষে" এবং "ধরা" ভাল হয়।


1
আপনার উদাহরণে, ত্রুটি হ্যান্ডলার কেবল $ HTTP ত্রুটিগুলি পরিচালনা করে।
বেনিয়ামিন গ্রুইনবাউম

1
হ্যাঁ, আমার এখনও সাফল্য / ত্রুটি ফাংশনগুলিতে ব্যতিক্রমগুলি পরিচালনা করতে হবে। এবং তারপরে আমার একধরনের সাধারণ হ্যান্ডলারের প্রয়োজন (যেখানে আমি জিনিসগুলি সেট করতে পারি loading = false)
জোয়েল

1
আপনার তত্ক্ষণাত () কল বন্ধ করার কারণে বন্ধনীগুলির পরিবর্তে আপনার ব্রেস রয়েছে।
পল ম্যাকক্লেইন

1
এটি 404 প্রতিক্রিয়া .catch()
ত্রুটিতে

নিয়ন্ত্রকদের কাছে ফিরিয়ে দেওয়া HTTP ত্রুটিগুলি পরিচালনা করার জন্য এটি সঠিক উত্তর
লিওন

5

কৌণিক $ http ক্ষেত্রে, সাফল্য () এবং ত্রুটি () ফাংশনটিতে প্রতিক্রিয়াযুক্ত বস্তুটি মোড়ানো হবে, সুতরাং কলব্যাক স্বাক্ষরটি $ http (...) এর মতো হবে success সাফল্য (ফাংশন (ডেটা, স্থিতি, শিরোনাম, কনফিগারেশন))

তারপরে () এর জন্য, আপনি সম্ভবত কাঁচা প্রতিক্রিয়ার বস্তুটি মোকাবেলা করবেন। যেমন AngularJS $ HT API ডকুমেন্টে পোস্ট করা

$http({
        url: $scope.url,
        method: $scope.method,
        cache: $templateCache
    })
    .success(function(data, status) {
        $scope.status = status;
        $scope.data = data;
    })
    .error(function(data, status) {
        $scope.data = data || 'Request failed';
        $scope.status = status;
    });

পূর্ববর্তী প্রতিশ্রুতি শৃঙ্খলে যদি নতুন ত্রুটি না ঘটে তবে শেষ .ক্যাচের (...) প্রয়োজন হবে না।


2
সাফল্য / ত্রুটি পদ্ধতিগুলি হ্রাস করা হয়।
ওভারমারস

-3

ব্র্যাডলি ব্রেথওয়েট তার ব্লগে যেমন পরামর্শ দেয় আমি এটি করি :

app
    .factory('searchService', ['$q', '$http', function($q, $http) {
        var service = {};

        service.search = function search(query) {
            // We make use of Angular's $q library to create the deferred instance
            var deferred = $q.defer();

            $http
                .get('http://localhost/v1?=q' + query)
                .success(function(data) {
                    // The promise is resolved once the HTTP call is successful.
                    deferred.resolve(data);
                })
                .error(function(reason) {
                    // The promise is rejected if there is an error with the HTTP call.
                    deferred.reject(reason);
                });

            // The promise is returned to the caller
            return deferred.promise;
        };

        return service;
    }])
    .controller('SearchController', ['$scope', 'searchService', function($scope, searchService) {
        // The search service returns a promise API
        searchService
            .search($scope.query)
            .then(function(data) {
                // This is set when the promise is resolved.
                $scope.results = data;
            })
            .catch(function(reason) {
                // This is set in the event of an error.
                $scope.error = 'There has been an error: ' + reason;
            });
    }])

গুরুত্বপূর্ণ দিক:

  • সমাধান নিয়ন্ত্রণের ফাংশনটি আমাদের নিয়ামকটিতে .টির ফাংশনের সাথে লিঙ্ক করে অর্থাৎ সমস্ত কিছু ঠিক আছে, তাই আমরা আমাদের প্রতিশ্রুতি রাখতে পারি এবং এটি সমাধান করতে পারি।

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

এটি বেশ স্থিতিশীল এবং নিরাপদ এবং যদি প্রতিশ্রুতি প্রত্যাখ্যান করার অন্যান্য শর্ত থাকে তবে আপনি সর্বদা সাফল্য ফাংশনে আপনার ডেটা ফিল্টার করতে পারেন এবং deferred.reject(anotherReason)প্রত্যাখ্যানের কারণ সহ কল করতে পারেন।

রায়ান ভাইস মন্তব্যগুলিতে যেমন পরামর্শ দিয়েছেন , আপনি প্রতিক্রিয়াটি কিছুটা ভাবেন না, তবে কথা বলতে না পারলে এটি কার্যকর হিসাবে দেখা যাবে না।

কারণ successএবং error১.৪ থেকে অবহেলিত হতে পারে নিয়মিত প্রতিশ্রুতি পদ্ধতি ব্যবহার করা thenএবং catchসেই পদ্ধতিগুলির মধ্যে প্রতিক্রিয়াটি রূপান্তর করা এবং সেই রূপান্তরিত প্রতিক্রিয়ার প্রতিশ্রুতি ফিরিয়ে দেওয়া ভাল।

উভয় পদ্ধতির সাথে এবং তৃতীয় অভ্যন্তরীণ পদ্ধতির সাথে আমি একই উদাহরণটি প্রদর্শন করছি:

successএবং errorযোগাযোগ করুন ( successএবং errorএইচটিটিপি প্রতিক্রিয়ার প্রতিশ্রুতি ফিরিয়ে দিন, সুতরাং আমাদের $qডেটার প্রতিশ্রুতি ফেরত দেওয়ার জন্য আমাদের সহায়তা প্রয়োজন ):

function search(query) {
  // We make use of Angular's $q library to create the deferred instance
  var deferred = $q.defer();

  $http.get('http://localhost/v1?=q' + query)
  .success(function(data,status) {
    // The promise is resolved once the HTTP call is successful.
    deferred.resolve(data);              
  })

  .error(function(reason,status) {
    // The promise is rejected if there is an error with the HTTP call.
    if(reason.error){
      deferred.reject({text:reason.error, status:status});
    }else{
      //if we don't get any answers the proxy/api will probably be down
      deferred.reject({text:'whatever', status:500});
    }
  });

  // The promise is returned to the caller
  return deferred.promise;
};

thenএবং catchপদ্ধতির (এটি ছোঁড়ার কারণে পরীক্ষা করা কিছুটা বেশি কঠিন):

function search(query) {

  var promise=$http.get('http://localhost/v1?=q' + query)

  .then(function (response) {
    // The promise is resolved once the HTTP call is successful.
    return response.data;
  },function(reason) {
    // The promise is rejected if there is an error with the HTTP call.
    if(reason.statusText){
      throw reason;
    }else{
      //if we don't get any answers the proxy/api will probably be down
      throw {statusText:'Call error', status:500};
    }

  });

  return promise;
}

যদিও অর্ধেক সমাধান রয়েছে (এইভাবে আপনি এড়াতে পারবেন throwএবং যাইহোক $qআপনার পরীক্ষাগুলিতে প্রতিশ্রুতি আচরণকে উপহাস করার জন্য আপনার সম্ভবত ব্যবহারের প্রয়োজন হবে ):

function search(query) {
  // We make use of Angular's $q library to create the deferred instance
  var deferred = $q.defer();

  $http.get('http://localhost/v1?=q' + query)

  .then(function (response) {
    // The promise is resolved once the HTTP call is successful.
    deferred.resolve(response.data);
  },function(reason) {
    // The promise is rejected if there is an error with the HTTP call.
    if(reason.statusText){
      deferred.reject(reason);
    }else{
      //if we don't get any answers the proxy/api will probably be down
      deferred.reject({statusText:'Call error', status:500});
    }

  });

  // The promise is returned to the caller
  return deferred.promise;
}

যে কোনও ধরণের মন্তব্য বা সংশোধন স্বাগত।


2
প্রতিশ্রুতিতে প্রতিশ্রুতি মোড়ানোর জন্য আপনি কেন $ q ব্যবহার করবেন। শুধু the http.get () দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি কেন ফিরিয়ে দিবেন না?
রায়ান ভাইস

কারণ success()এবং error()হিসাবে নতুন প্রতিশ্রুতি ফেরত then()দেয় না। $qআমরা আমাদের কারখানাকে এইচটিটিপি প্রতিক্রিয়া দেওয়ার প্রতিশ্রুতির পরিবর্তে ডেটার প্রতিশ্রুতি ফিরিয়ে আনার সাথে তৈরি করি।
ওয়াচ মেকার

আপনার প্রতিক্রিয়া আমার কাছে বিভ্রান্ত করছে তাই সম্ভবত আমি নিজেকে ভালভাবে ব্যাখ্যা করছি না। যদি না আপনি প্রতিক্রিয়াটি হেরফের করছেন তবে আপনি কেবল সেই প্রতিশ্রুতিটি ফিরিয়ে দিতে পারবেন $ HTTP ফেরত returns এই উদাহরণটি আমি স্রেফ লিখেছি দেখুন: jsbin.com/belagan/edit?html,js
রায়ান ভাইস

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

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