синтаксис для Jquery.deferred , обеспечивающий обещание возврата синхронной функции
-
11-12-2019 - |
Вопрос
Быстрый вопрос о том, как использовать 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