В чем разница между объектом Deferred и его собственным объектом обещания?

Давайте создадим простой объект Deferred:

defer = $.Deferred( function ( defer ) {
    setTimeout( defer.resolve, 3000 );
});

Вышеупомянутый объект Deferred будет находиться в состоянии «ожидание» в течение 3 секунд, а затем переключится в состояние «разрешено» (после чего будут вызваны все связанные с ним обратные вызовы).

Давайте также получим обещание этого объекта Deferred:

promise = defer.promise();

Теперь, чтобы добавить обратные вызовы, которые будут вызываться после разрешения объекта Deferred, мы можем использовать .done() или .then(). Однако мы можем вызвать этот метод как для самого объекта Deferred, так и для его собственного объекта обещания.

defer.then( handler );

or

promise.then( handler );

В обоих случаях будет вызвана функция handler (в данном случае через 3 секунды).

Если мы используем $.when, мы можем снова передать сам объект Deferred или его объект обещания:

$.when( defer ).then( handler );

or

$.when( promise ).then( handler );

Опять же, между приведенными выше двумя строками кода нет никакой разницы.

Текущая демонстрация: http://jsfiddle.net/G6Ad6/

Итак, мой вопрос заключается в том, что, поскольку мы можем вызывать .then(), .done() и т. д. для самого объекта Deferred и поскольку мы можем передать этот объект Deferred в $.when(), какой смысл в .promise() и получении объекта обещания? Какова цель объекта обещания? Почему такая избыточность в функциональности?


person Šime Vidas    schedule 10.11.2011    source источник


Ответы (3)


Он создает «запечатанную» копию отложенного значения без методов .resolve() и .reject(). Из документации:

Метод deferred.promise() позволяет асинхронной функции предотвратить вмешательство другого кода в ход выполнения или состояние ее внутреннего запроса.

Он используется, когда изменение значения не имеет смысла. Например, когда jQuery делает запрос AJAX, он возвращает объект обещания. Внутри это .resolve()значение для исходного объекта Deferred, который пользователь наблюдает с обещанием.

person Jeremy    schedule 10.11.2011
comment
Ах, это запечатанная копия, да,... это объясняет. - person Šime Vidas; 10.11.2011
comment
Чтобы добавить к этому, что сделало это намного яснее для меня, из docs: Promise Object - Этот объект предоставляет подмножество методов объекта Deferred (затем, выполнено, сбой, всегда, канал и состояние), чтобы пользователи не могли изменить состояние объекта Deferred. - person Nick M; 09.02.2015

При использовании «обещания» отложенного объекта наблюдатели (например, объекты, ожидающие разрешения) не имеют прямого доступа к самому отложенному объекту, поэтому они не могут, например, вызвать метод «Разрешить» этого отложенного. Это способ защиты оригинального Deferred.

person ElLocoCocoLoco    schedule 18.12.2013

С помощью Deferred вы можете контролировать его состояние set.

Когда дело доходит до обещания, вы можете прочитать состояние и, возможно, прикрепить обратный вызов. get

person serkan    schedule 12.11.2015