2010-12-03 3 views
9

Мне нужно написать функцию в JavaScript, которая возвращает состояние от вызова асинхронной функции. Однако вызывающий абонент получает только значение, и функция обратного вызова не должна предоставляться. Я пытался что-то вроде:Как заблокировать асинхронные функции в JavaScript

function getState() { 
    var ret = null; 
    asyncCall("request", 
     function() { ret = "foo"; } // callback 
    ); 
    while (ret === null) 
     ; // block on the asynchronous call 
    return ret; 
} 

Однако, цикл никогда не кончится ...

Есть идеи? Спасибо.

+2

Почему вы хотите заблокировать асинхронный вызов в первую очередь? Делать это не имеет смысла. – Tomalak 2010-12-03 13:30:21

+1

@Tomolak: потому что это звонок от Firefox, и я не могу его изменить. Ожидается, что это займет не больше миллисекунд, я не хочу реорганизовывать весь мой другой код только из-за этого. – 2010-12-03 13:32:49

+0

Можете ли вы опубликовать функцию, которая вызывает `getState()`? – Tomalak 2010-12-03 13:39:39

ответ

8

Я думаю, что вы ищете StratifiedJS, http://stratifiedjs.org Это позволяет «организовать» свою асинхронную код в точности, как вы написали, BEWARE, что он «пишет», как синхронный код , он НЕ будет блокировать остальную часть вашего приложения. Вы можете использовать его в любом месте, загрузив библиотеку apollo js.

Вот как это будет выглядеть в стратифицированной JavaScript:

function getState() { 
    waitfor (var ret) { 
    // block on the asynchronous call 
    asyncCall("request", resume); 
    } 
    return ret; 
} 

, конечно, есть модули/библиотеки, которые бы просто сделать его выглядеть следующим образом: http://onilabs.com/modules#http

function getState() { 
    return http.get("request"); 
} 
0

Почему не просто:

asyncCall("request", function() { 
    // here you can inspect the state 
}); 

Какой смысл функции обертки?

Асинхронные функции работают таким образом. Если вы хотите, чтобы блокировать выполнение, а затем использовать синхронный вызов:

var state = syncCall("request"); 
1

Лучше всего было бы поставить логику вы хотите назвали в функцию обратного вызова. Есть ли причина, по которой вы не можете этого сделать?

Вы можете использовать setInterval, чтобы проверить результат, но требует функцию обратного вызова, тоже ...

1

Если я не понял ваш вопрос, вы можете посмотреть событие jQuery ajaxStop() - http://api.jquery.com/ajaxstop. Это блокируется до тех пор, пока все вызовы ajax не будут завершены. Это, очевидно, требует, чтобы все ваши асинхронные вызовы выполнялись через jQuery.

$(document).ajaxStop(function() { 
    // do your "ajax dependent" stuff here 
}); 
Смежные вопросы