Поддержка браузера Promise.defer()

Я ищу способ создать отложенный объект, который будет разрешен за пределами текущей области. Мне нравятся отложенные объекты, и, как я вижу, Promise.defer() в Chrome 38 возвращает отложенный объект.

Но в последнем Firefox 34 Promise.defer также не определено в Safari 8.0.

Так что теперь я не могу везде использовать Promise.defer. Что насчет будущего статуса? Будет ли он реализован в других браузерах или будет удален как устаревший?


person just-boris    schedule 11.01.2015    source источник
comment
Ну, вы можете создать собственный отложенный объект, используя Promise, если вы действительно этого хотите.   -  person dfsq    schedule 11.01.2015
comment
Его планируется удалить из Chrome, а также chain.   -  person Benjamin Gruenbaum    schedule 11.01.2015
comment
Promise.defer() перестал работать у меня в Google Chrome. (Версия 52.0.2743.82)   -  person Andrew Shepherd    schedule 27.07.2016


Ответы (2)


Согласно статье MDN об отложенных, .defer метод устарел. Если вы посмотрите на эту ошибку, там написано, что Promise.defer нестандартен, так что вряд ли вернется.

Начиная с Gecko 30, этот объект устарел и больше не должен использоваться. Вместо этого используйте конструктор new Promise().

Они предлагают пример того, как переписать код Promise.defer, чтобы вместо него использовать new Promise.

Promise.defer

var deferred = Promise.defer();
doSomething(function cb(good) {
    if (good)
        deferred.resolve();
    else
        deferred.reject();
});
return deferred.promise;

новое обещание

return new Promise(function(resolve, reject) {
    doSomething(function cb(good) {
        if (good)
            resolve();
        else
            reject();
    });
});

У нового формата есть несколько преимуществ, в том числе более чистый код и повышенная безопасность бросков (если код в функции инициализации промиса выбрасывает синхронно, промис будет отклонен).

person Alexander O'Mara    schedule 11.01.2015
comment
Стоит упомянуть, почему он был удален — конструктор промисов безопасен для бросков, в отличие от отложенных. Если вы добавите область действия конструктора промисов, он преобразует его для вас в отклонение. - person Benjamin Gruenbaum; 11.01.2015
comment
@BenjaminGruenbaum, спасибо, я действительно это имею в виду. - person just-boris; 11.01.2015
comment
более полное почему: Разница между defer().promise и Promise - person Bergi; 24.02.2015
comment
Однако возможность разрешить или отклонить промис (отложенный) на расстоянии, вне конструктора, теряется. - person Michael Trouw; 22.03.2018
comment
Итак, когда обещание должно быть разрешено/отклонено вне конструктора, что мы делаем сейчас? ответ dfsq? - person Greendrake; 19.07.2020

Хотя я сомневаюсь, что это хорошая идея, но технически вы можете реализовать собственный отложенный объект на основе промисов. Например:

function defer() {
    var deferred = {};
    var promise = new Promise(function(resolve, reject) {
        deferred.resolve = resolve;
        deferred.reject  = reject;
    });
    deferred.promise = promise;
    return deferred;
}

var deferred = defer();

deferred.promise.then(function(data) {
    document.body.innerHTML += '<p>Resolved: ' + data + '</p>';
});

document.body.innerHTML = '<p>Deferred created.</p>';

setTimeout(function() {
    deferred.resolve(123);
}, 2000);

person dfsq    schedule 11.01.2015
comment
это считается анти-шаблоном Promise, потому что он не позволяет правильно распространять ошибки - person Alnitak; 11.01.2015
comment
@Alnitak Я знаю это, поэтому я сказал, что это не очень хорошая идея. Я только что продемонстрировал, что реализовать отложенный объект технически возможно. - person dfsq; 11.01.2015
comment
@Alnitak это не имеет ничего общего с распространением ошибок - вы путаете отложенный анти-шаблон с созданием обещания с отложенным. - person Benjamin Gruenbaum; 11.01.2015
comment
@BenjaminGruenbaum И раз уж вы здесь, было бы очень интересно, как бы вы ответили на вопрос ОП? Потому что мое решение кажется неудобным. - person dfsq; 11.01.2015
comment
@BenjaminGruenbaum ой, забыл, в чем проблема - person Alnitak; 11.01.2015
comment
@dfsq Я проголосовал за ваше решение как прагматичное, и решение, предоставленное Александром О'Мара, правильное. Я не уверен, что я могу добавить сюда. - person Benjamin Gruenbaum; 11.01.2015
comment
Спасибо за ответы! Но когда я знаю о риске неперехваченных исключений, могу ли я извлечь отложенные исключения, как показано здесь? - person just-boris; 11.01.2015
comment
@just-boris yes - конструктор промисов гарантированно запускает переданный ему код синхронно, поэтому описанный выше подход гарантированно работает успешно. Извлечение отложенного было одним из основных соображений, когда было наложено ограничение на его синхронный запуск. Это гарантированно работает в каждом браузере и в каждой библиотеке, реализующей спецификацию конструктора промисов. - person Benjamin Gruenbaum; 11.01.2015
comment
Для будущих читателей, задумавшихся над этим вопросом. Упомянутый антипаттерн Promise связан с неперехваченными исключениями. Это происходит, когда инициирующая функция обратного вызова выдает исключение, и оно должно перейти к обработчику отклонения, но этого не происходит. Дополнительная информация на bytearcher.com/articles/pitfalls-of-promisifying-by- группа - person pspi; 05.11.2015
comment
Это помогает мне. Меня попросили использовать пакет sharepoint, я столкнулся со случаем, когда функция вызова является executeQueryAsync, успешный и неудачный ответ находятся в двух отдельных функциях. Я должен использовать отложенный, чтобы установить успешный и неудачный ответ один за другим. - person sbk201; 31.07.2018