ฉันทำเหมือน Bradley Braithwaite แนะนำในบล็อกของเขา:
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;
});
}])
ประเด็นสำคัญ:
ฟังก์ชันแก้ไขจะเชื่อมโยงไปยังฟังก์ชัน. then ในคอนโทรลเลอร์ของเรานั่นคือทุกอย่างเรียบร้อยดีดังนั้นเราจึงสามารถรักษาสัญญาและแก้ไขได้
ฟังก์ชันปฏิเสธจะเชื่อมโยงไปยังฟังก์ชัน. จับในตัวควบคุมของเรานั่นคือมีบางอย่างผิดพลาดเราจึงไม่สามารถรักษาสัญญาและจำเป็นต้องปฏิเสธมัน
ค่อนข้างเสถียรและปลอดภัยและหากคุณมีเงื่อนไขอื่น ๆ ที่จะปฏิเสธคำสัญญาคุณสามารถกรองข้อมูลของคุณในฟังก์ชันความสำเร็จและโทรหาdeferred.reject(anotherReason)
ด้วยเหตุผลของการปฏิเสธได้
ตามที่ Ryan Vice แนะนำในความคิดเห็นสิ่งนี้อาจไม่ถูกมองว่ามีประโยชน์เว้นแต่คุณจะตอบสนองเล็กน้อยเพื่อที่จะพูด
เพราะsuccess
และerror
มีการเลิกใช้ตั้งแต่ 1.4 บางทีมันอาจจะดีกว่าที่จะใช้วิธีการสัญญาปกติthen
และcatch
และเปลี่ยนการตอบสนองภายในวิธีการเหล่านั้นและกลับสัญญาของการตอบสนองที่เปลี่ยน
ฉันกำลังแสดงตัวอย่างเดียวกันกับทั้งสองวิธีและวิธีที่สามระหว่างกัน:
success
และerror
วิธีการ ( success
และerror
ส่งคืนสัญญาของการตอบสนอง HTTP ดังนั้นเราต้องการความช่วยเหลือใน$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;
}
ยินดีรับฟังความคิดเห็นหรือการแก้ไขใด ๆ
success()
อย่างไรerror()
และfinally()
รวมกับcatch()
? หรือฉันต้องใช้then(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);