2013-08-14 8 views
7

Мне интересно, как имитировать обещание $ http, когда я знаю, что запрос не удастся на стороне сервера. Вот мой код:AngularJS Promises - имитировать http-обещания

if (!ng.isString(email)) { 
    var promise = $q.defer().promise; 
    $q.reject(); 

    return promise; 
} 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}) 

// Success handler 
.success(response){ return response}) 

// Error handler 
.error(errorMsg){ return errorMsg}); 
+1

ли promise.reject() вместо $ q.reject(); –

+0

Я получаю следующее сообщение об ошибке: Объект # не имеет метода 'reject' – Frank6

+0

ли проверка на isString имеет какое-либо отношение к функции $ http после этого? Пожалуйста, упростите вашу ссылку – nXqd

ответ

5

Хорошо, я мог бы выяснить, как имитировать то же обещание, которое возвращается объектом $ http. Спасибо всем за ваши ответы. Я мог бы принять их всех во внимание. Вот мое решение:

if (!ng.isString(email)) { 

    // We need to create a promise like the one returned by the 
    // $http object (with the success and error methods) 
    // to stay consistent. 
    var promise = $q.reject("error with email"); 

    // Defining success and error method for callbacks. 
    // but it should never be called since the promise 
    // is already rejected. 
    promise.success = function(fn){ 
     promise.then(function(response){ 
      fn(response) 
     }, null); 
      return promise 
    }; 

    promise.error = function(fn){ 
     promise.then(null, function(response){ 
      fn(response) 
     }); 
     return promise; 
    }; 

    return promise; 
} 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}) 

// Success handler 
.success(response){ return response}) 

// Error handler 
.error(errorMsg){ return errorMsg}); 
+1

Мне интересно, почему методы' success' и 'error' еще не определены в обещании. Похоже, было бы полезно, не так ли? – Frank6

+1

Мне нужно было сделать что-то подобное. Мое решение схоже, но я подумал, что буду указывать, что 'обещание.then (function (response) {fn (response);})' фактически совпадает с 'prom.then (fn)'. –

0

Ваш синтаксис немного перепутался. Попробуйте вместо этого:

var deferred = $q.defer(); 
$q.reject(); 
return deferred.promise; 
+0

Спасибо за ваш ответ! Но из-за того, что мне нужно использовать метод 'success' и' error' вместо 'then', я получаю следующую ошибку: Object # не имеет метода 'success' – Frank6

+0

Борьба с различными интерфейсами обещаний между HttpPromise и Promise –

5

Вы можете использовать решение и отказаться, чтобы контролировать поток ваших данных:

Допустим, у вас есть услуга, как это:

var app = angular.module("mymodule.services", []); 

app.factory("HttpRequest", ['$q', '$http', function(q, http) { 
    var deferredData = q.defer(); 

    http.get('http://your-server.local/data.json').success(function(data) { 
    //success, resolve your promise here 
    deferredData.resolve(data); 
    }).error(function(err) { 
    //error, use reject here 
    deferredData.reject(err); 
    }); 

    return { 
    get: function() { 
     return deferredData.promise; 
    } 
    }; 
}]); 

Услуга может затем быть используемые как таковые:

var app = angular.module("mymodule.controllers", ['mymodule.services']); 

app.controller("MyCtrl", ['HttpRequest', '$scope', function(res, scope) { 
    //the "then"-method of promises takes two functions as arguments, a success and an erro callback 
    res.get().then(function(data) { 
    //first one is the success callback 
    scope.data = data; 
    }, 
    function(err) { 
    scope.err = err; 
    }); 
}]); 

Вы можете обработать ошибку во втором обратном вызове.

+0

Спасибо за ваш ответ!Звучит неплохо, но мне нужно использовать метод 'success' и' error' вместо 'then' – Frank6

+0

Обещания, которые' 'q q предлагает в угловом режиме, не имеют этих методов из коробки, я предложил их изменить здесь: http://stackoverflow.com/questions/17686612/rejecting-promises-with-multiple-arguments-like-http-in-angularjs/17687321#17687321 – Florian

1

Что-то, как это должно работать:

if (!ng.isString(email)) 
    return $q.reject("Email is invalid."); // returns rejected promise 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}); 

то в вашем коде использовать его как обычный обещание

mypromise.then(function(x) { do something with x.data }, function(error) { alert(error)}); 
+0

Спасибо за ваш ответ! Звучит неплохо, но мне нужно использовать метод 'success' и' error' вместо 'then' ... – Frank6

3

$http возвратного обещание в angularJS. Вы можете сделать так:

var promise = $http(...) ; 
promise.then(function(data) {}, function(error){}); 

Вы можете посмотреть на успех и функции ошибок в JQuery Ajax вызова, но это другое дело, что здесь работает в angularJS. Возможно, вам придется следовать за ним, чтобы он работал правильно.

Вы можете рассказать нам больше о причине, по которой вам нужно использовать успех и ошибку, чтобы мы могли найти способ заставить его работать с вашим делом.

1

Играя с предложением ниже (и отладкой Angularjs коды), я нашел более простой способ, который позволяет отклонить или решить.

if (alreadyLoaded){ 
    var defered = $q.defer(); 
    defered.success = function(fn){ 
     defered.promise.then(fn); 
     return defered; 
    }; 
    defered.error = function(fn){ 
     defered.promise.then(null, fn);//or defered.promise.catch(fn) 
     return defered; 
    }; 
    if(data.invalid) 
     defered.reject("arbitrary error"); 
    else 
     defered.resolve(data); 
    return defered; 
}else { 
    return $http.get(...); 
} 

(оба success и error методы возвращают this, чтобы обратные вызовы в очереди)