JavaScript обещает путаницу

Я пытаюсь понять концепцию обещания javascript. Но у меня возникают некоторые проблемы. Я установил очень маленький веб-сервис локально (не сердитесь, веб-сервис не соответствует соглашениям). Вот некоторые подробности об этом

/login/<username>/<password> ==> авторизуйтесь в системе, правильный логин и пароль не нужны

если пользователь входит в систему, вызов может быть сделан на /car/<brand>/<color>/<plate_number>,

Я не выполняю проверку типа цвета, марки, номерного знака

Этот работает отлично, я регистрируюсь и добавляю машину

$.ajax({type: "GET",url: url+"/login/noor/noor"})
                .then(function( data, textStatus, jqXHR ) {console.log("login success");},function(){console.log("login error");})
                .then($.ajax({type: "GET",url: url+"/car/1/1/1"}))
                .then(function(){console.log("car added");},function(){console.log("car not added");});

Этот отлично показывает ошибку, потому что используется недопустимый URL:

$.ajax({type: "GET",url: url+"/carasdsad/1/1/1"})
                .then(function(){console.log("car added");},function(){console.log("car not added");});

"/carasdsad/1/1/1" является недопустимым URL-адресом, и возвращается автомобиль не добавлен.

У меня проблема с этим. Код ниже использует код чуть выше. Я ожидал, что будет показано автомобиль не добавлен, а оказалось автомобиль добавлен.

$.ajax({type: "GET",url: url+"/login/noor/noor"})
                .then(function( data, textStatus, jqXHR ) {console.log("login success");},function(){console.log("login error");})
                .then($.ajax({type: "GET",url: url+"/carasdsad/1/1/1"}))
                .then(function(){console.log("car added");},function(){console.log("car not added");});

Приведенный выше код возвращает автомобиль добавлен, хотя "/carasdsad/1/1/1" является недопустимым URL-адресом во втором вызове.


person Noor    schedule 25.03.2014    source источник


Ответы (2)


Согласно spec, нефункциональный аргумент игнорируется в методе then.

Ваш код, приведенный к минимальному регистру, выглядит так:

Promise.resolve(true)
    .then(Promise.reject("some err"))
    .catch(console.log.bind(console, "fail"));

И нужно переписать его таким образом, чтобы ловить ошибки:

Promise.resolve(true)
    .then(function(){ return Promise.reject("some err") })
    .catch(console.log.bind(console, "fail"));
person kirilloid    schedule 25.03.2014
comment
Почему-то я все еще думаю, что это не произойдет с настоящей библиотекой обещаний, такой как BlueBird :-) - person John Dvorak; 25.03.2014
comment
Что вы подразумеваете под настоящей библиотекой? Да, jQuery не соответствует спецификации A+, но я протестировал свой пример с нативными промисами в Chrome. - person kirilloid; 25.03.2014
comment
Тем не менее, deferred.then ожидает функции в качестве аргументов. - person kirilloid; 25.03.2014
comment
@JanDvorak: Что ж, Bluebird ведет себя так же, но регистрирует предупреждение об этой ошибке новичка, заключающейся в передаче обещания вместо обратного вызова :-) - person Bergi; 18.05.2016

простая реализация Promise

(пожалуйста, используйте Chrome/Firefox)

function mPromise(executor) {
this.status = null;
this.result = null;
that=this;
executor(function(result) {
    that.status = "fullfiled";
    that.result = result;
}, function(result) {
    that.status = "rejected";
    that.result = result;
})};

mPromise.prototype.then = function(f, r) {
if (this.status == "fullfiled") {
    f(this.result);
} else {
    r(this.result);
}}

Сначала создайте объект Promise:

var a = new mPromise(function(fFlagFun, rFlagFun) {
setTimeout(function() { //using setTimeout mimic remote request
    fFlagFun("yes"); //here you can try rFlagFun("no") by hand;
}, 3000);});

Затем через 3 секунды выполните следующий фрагмент кода:

a.then(function(e) {console.log(e);}, function(e) {console.log(e);})

Если вы протестируете его в других формах, он может дать сбой. Я надеюсь, что приведенный выше код даст вам общее представление о концепции Promise.

person wengeezhang    schedule 16.01.2015
comment
Это не только неправильно, но и скорее отвечает на вопрос Как реализована библиотека promise/defer?, чем этот. - person Bergi; 18.05.2016