2013-07-19 5 views
2

Я хотел бы написать функцию, которая выполняет обратный вызов и вызывает его после выполнения функции.Обратные вызовы, которые не блокируются

Это очень просто:

var callback = function (ref) { 
    var i = 1337; 
    while (i--) { 
     console.log(ref, 'callback'); 
    } 
}; 

var someFoo = function (ref, callback) { 
    console.log(ref, 'self'); 

    callback(ref); 
} 

someFoo('one', callback); // 1 
someFoo('two', callback); // 2 

Но здесь я столкнулся с этой проблемой: сначала someFoo блоки вызова до тех пор, пока Allback закончена. Это означает, что этот код эквивалентен этому (который блокирует, пока каждая функция не закончена):

someFoo('one'); 
callback('one'); 
someFoo('two'); 
callback('two'); 

Теперь вопрос: Как сделать асинхронный обратный вызов вызов?

ответ

9

Изменение:

callback(ref); 

To:

setTimeout(function(){ callback(ref); }, 0); 

Или, так как вы пишете расширение хром, и, следовательно, не придется беспокоиться о старых браузерах, вы можете использовать bind :

setTimeout(callback.bind(null, ref), 0); 
+0

Это похоже на грязный хак. Существуют ли также «официальные» способы? –

+3

@WaleryStrauch Nope, только другие способы будут более грязными. – Paulpro

+1

Это не грязный хак. JavaScript-код синхронно, как ответил Майк Томпсон. Единственный источник «асинхронного» исполнения - это внешнее влияние (например, браузер, отвечающий на события или таймеры). – Sacho

2

JavaScript, реализованный в браузерах, является однопоточным, поэтому вы не можете выполнить команду rea l асинхронный вызов. Что вы можете сделать что-то вроде этого, приближена:

setTimeout(function() { 
    callback(ref); 
}, 1000); 

Где 1000 1 секунда в миллисекундах (задержка в дальнейшем по мере необходимости). Однако, поскольку однопоточное обратное соединение все равно блокирует другой выполняемый код.

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

+0

Это расширение хром в моем случае, поэтому мне не важно IE (или более старый браузер) –

+0

Я не думаю, что ответ, который вы выбрали, действительно помогает вам, потому что все, что он делает, произвольно выполняет кусок кода в данный момент времени в пределах одного потока. Вам просто нужно будет укусить пулю и сохранить настройку, пока вы не найдете что-то более очевидное синхронное, которое работает быстро. –

+0

@MikeThomsen 'setTimeout' гарантирует, что обратный вызов выполняется через некоторое время после завершения текущего потока выполнения. Вот как работает цикл событий Javascript. Это не произвольно, и он не будет блокировать какой-либо другой исполняемый код, поскольку он не будет работать, пока не завершится какой-либо другой код (который уже запущен). – Paulpro

Смежные вопросы