2016-06-10 1 views
0

Я ищу, чтобы увидеть, есть ли способ использовать общую функцию асинхронизации, такую ​​как AJAX или веб-рабочий в сообщении, и заставить его вести себя синхронно.javascript синхронные обратные вызовы

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

Если нет универсального решения, я бы согласился на тот, который работает исключительно на Worker.prototype.onmessage, так как здесь используется основной вариант использования.

Я уверен, что ответ будет «это невозможно», но я хотел проверить перед сдачей.

Я уже рассмотрел обещания и генераторы, я бы предпочел не использовать стороннюю библиотеку (я знаю о волокнах/фьючерсах для узла).

Потенциальный случай использование:

function main(){ 
    worker = new Worker("someWorker.js") 
    var result = worker.onmessage(function(event){ 
     return event.data; 
    }) 
    //wait for worker.onmessage 
    return result; 
} 
+0

Связанный вопрос jQuery: http://stackoverflow.com/q/133310/901048 – Blazemonger

+0

@Blazemonger, спасибо - но это будет работать только для вызовов ajax. Определенно стоит отметить, хотя –

+0

Просто запустите работника и поместите весь синхронный код, который зависит от результата работы, в обратном вызове 'onmessage'. Обещания и генераторы просто решают одну и ту же проблему с большей элегантностью. – Vaclav

ответ

-1

Если вы хотите сохранить синхронный поток функции, функция генератора является единственно возможным решением. Вы отправите все асинхронные задачи, например var result = yield new Worker('someWorker.js').

Вне function* main вы получите worker с mainFn.next().value, а затем прикрепить onmessage слушателя, который будет возвращать разрешенные данные в function* main и функция будет возобновлен.

Полный пример генератора выглядит следующим образом

// write function as generator 
function* main() { 
    var result = yield new Worker("someWorker.js"); 
    return result; 
} 

// instantiate the generator and get the first yield value 
var mainFn = main() 
    , worker = mainFn.next().value 

// set onmessage listener, which is callback, that sends data back to *main() 
worker.onmessage = function(event) { 
    mainFn.next(event.data); 
} 

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

Вы, кажется, знаете, что такое генераторы и что он широко не поддерживается в браузерах, поэтому, если вы хотите запустить этот код на веб-странице, вам понадобится transpiler ES6 Babel.

+0

Это не работает, потому что последующие вызовы 'mainFn.next()' не ждут для 'worker.onmessage' –

+0

@ZackNewsham первый вызов' next() 'выводит' Worker' из 'main()', второй вызов 'next()' передает 'event.data' обратно в' main()) ', который заменяет« Рабочий »на' event.data' и возобновляет 'main()'. Второй вызов 'mainFn.next()' помещается внутри обратного вызова, поэтому он ждет сообщения о событиях точно, но возможно, что ваш рабочий возвращает несколько сообщений. В этом случае вы хотите скопировать сообщения в какую-либо переменную, а затем после завершения данных переведите их обратно в 'main()' с 'mainFn.next (completeData)'. – Vaclav

+0

Я пытался с тривиальным работником, может быть, что генератор реализован по-разному в разных браузерах (я использую Chrome). Кроме того, я использую это в Meteor, который компилирует код перед развертыванием, чтобы он мог возиться с вещами. –

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

  • Нет связанных вопросов^_^