синтаксис для Jquery.deferred , обеспечивающий обещание возврата синхронной функции

StackOverflow https://stackoverflow.com//questions/10664466

Вопрос

Быстрый вопрос о том, как использовать Jquery.deferred, чтобы медленная синхронная функция вместо этого возвращала обещание.Что я сделал до сих пор, так это:

function sayIt(ms) {
    setTimeout( function() { console.log('what I say'); }, ms);
} 

function doIt() {
    return $.Deferred( function() { sayIt(2000); }).promise();
}


doIt().then( function() { console.log('ah'); });

SayIt(2000) всегда выполняется, но связанная функция после 'then' никогда не срабатывает.

Если я сделаю это:

doIt().then( console.log('ah'));

сразу появляется «а», а затем через 2000 мс «то, что я говорю» - я, конечно, хочу обратного - чтобы через две секунды я получал «то, что я говорю», а затем сразу после этого «а».

Любые предложения приветствуются!

Это было полезно?

Решение

сделать что-то синхронно, но все еще используйте обещание:

function slowPromise() {

    var def = $.Deferred();

    // do something slow and synchronous
    ...

    // resolve the deferred with the result of the slow process
    def.resolve(res);

    // and return the deferred
    return def.promise();
}
.

Эффект состоит в том, что вы все еще получаете обещание, но это обещание уже разрешено, поэтому любой генеракодицетагкод, который впоследствии зарегистрирован на нем, продолжается немедленно.

Преимущество этого шаблона заключается в том, что если вы впоследствии замените синхронный код с чем-то асинхронной функцией, все еще имеет тот же внешний интерфейс.

Другие советы

Если вы хотите выполнить функцию после истечения таймаута, вам нужно вызвать resolve() на Deferred объект из функции истечения тайм-аута:

function sayIt(ms) {
  var d = $.Deferred();
  setTimeout(function() {
      console.log('what I say');
      d.resolve()
    }, ms);
  return d;
}

Таким образом, вы ограничиваете разрешение Deferred возражать против истечения таймаута.

Чтобы достичь того, что, как я считаю, является вашим намерением:

function doIt() {
  return sayIt(2000).promise()
}

А .promise() звонок не является обязательным.Он ограничивает только доступный интерфейс для вызывающих абонентов:вернув Promise вместо оригинала Deferred объекта, вызывающий объект может только реагировать на события, но не запускать их.Ссылка: http://api.jquery.com/deferred.promise/.

В конце концов, ваш первоначальный вызов:

doIt().then( function() { console.log('ah'); });

Выведет:

// 2 seconds delay
what I say
ah 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top