2013-07-26 1 views
0

Мне просто интересно, если в Firefox-аддоне можно вызвать функцию, которая будет ждать обратного вызова при вызове асинхронной функции. Это может быть потенциально полезно.Firefox addon: конвертировать асинхронный в синхронный

Например

function async_func(callback) { 
    ... 
    callback(2); 
} 

function callback_foo(x) { return x*x; } 
var results = Sync.wait_for_async_callback(async_func, callback_foo); 
// now, results is 2*2 = 4 
.... 

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

Но я нашел случайно this article, что может указывать на то, что это будет возможно. Однако я не могу найти необходимый модуль для этого (файл Sync.js). Link на эту статью не представляется полезным (ошибки в серверном коде?) Код Firefox на Mozilla-central не знает этот файл.

Возможно, веб-работники или nsIThreadManager могут быть другим способом конвертации async для синхронизации вызова.

+0

Почему вы не просто использовать обратный вызов? –

+0

@AdrianLang Я знаю, что обратный вызов, как правило, был бы хорошим решением, потому что он не застыл нить, но, например, обратный вызов не может использоваться, когда есть необходимость в возвращаемом значении в функции. Большая проблема заключалась бы в том, что что-то не поддерживает асинхронные функции, а только синхронизацию. Например, расширение Bookmark Favicon Change является [сломанным] (https://bugzilla.mozilla.org/show_bug.cgi?id=834457#c17), потому что ему необходимо переписать внутреннюю функцию Firefox, которая является синхронной, и Mozilla удалила некоторые функции синхронизации , Требуется возвращаемое значение, которое не может быть возвращено в обратном вызове. – Greck

ответ

1

Итак, я нашел Sync.js module. Он использует synchrounous ожидания для последующих событий по processNextEvent до обратного вызова не будет срабатывать:

let thread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread; 
while (async callback not fired yet) 
    thread.processNextEvent(true); 

Этот трюк, кажется, работает, но в соответствии с Марко Bonardo it is bad choice (падениям?)

+0

Некоторые примечания об использовании цикла форматирования событий: от [MDN] (https://developer.mozilla.org/en-US/docs/Code_snippets/Threads#Waiting_for_a_background_task_to_complete), [Andrew Sutherland] (https: //bugzilla.mozilla .org/show_bug.cgi? ID = 608095 # c0) – Greck

0

Это делается с Promises, читать {эта документация] (https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm), которая основана на this specification.

+0

Спасибо за ссылку. Однако он выглядит только как более удобный способ использования асинхронного кода. С помощью синхронного пути магическая функция async не активируется. Я могу получить результат асинхронного кода только в обратном вызове в функции 'prom.then'. – Greck