Сделать асинхронное событие синхронным в JavaScript - PullRequest
3 голосов
/ 06 февраля 2009

Я использую элемент управления WPF 3.5SP1 WebBrowser для отображения страницы, содержащей некоторые функции javascript. Затем моей программе нужно вызвать функцию javascript, которая сделает асинхронный вызов. Мне нужен способ получить результат этого асинхронного вызова обратно в C #, чтобы я мог обработать результат.

Есть ли способ заставить первую функцию JavaScript спать, пока что-то не произойдет (без блокировки браузера)?

edit: Я уже использую обратный вызов - вторая функция на самом деле называется some-async-function-complete. Он вызывается, когда завершается асинхронное событие. Теперь мне нужен способ получить результат в C #.

Для уточнения: C #

var result = WebBrowser.InvokeScript("myscript")

JavaScript

var result;

function myscript()
{
some-async-function();
/* what goes here? */
/* wait until result != null */
return result;
}

function some-async-function-complete(retval)
{
result = retval;
}

Ответы [ 5 ]

4 голосов
/ 06 февраля 2009

Есть ли способ сделать первый Функция Javascript спать до что-то происходит (без блокировки браузер)?

Да - вы можете использовать асинхронную функцию так, как это было задумано: передать ей обратный вызов и позволить ей делать свое дело. Вы должны быть в состоянии передать обратный вызов из C # в вашу функцию JS, которая затем может либо передать его вашей асинхронной функции напрямую, либо обернуть ее в другую функцию, если требуется постобработка.


Пример реализации обратного вызова - это работает с элементом управления WinForms WebBrowser, я не тестировал его с WPF, но они должны быть почти такими же:

[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Callback
{
   // allows an instance of Callback to look like a function to the script
   // (allows callback() rather than forcing the script to do callback.callMe)
   [System.Runtime.InteropServices.DispId(0)]
   public void callMe(string url)
   {
      // whatever you want to happen once the async process is complete
   }
}

...

Callback cb = new Callback();
WebBrowser.InvokeScript("myscript", new object[] { cb })

...

function myscript(callback)
{
   some_async_function(function()
   {
      // script-specific completion code
      if ( callback )
         callback();
   });
}
2 голосов
/ 06 февраля 2009

См. Связанный вопрос: Можете ли вы дождаться обратного вызова javascript?

Цитата из цитаты в мой ответ на этот вопрос:

JavaScript Strands добавляет сопрограмму и совместная поддержка потоков Язык JavaScript для включения блокировки возможности для асинхронного события Обратные вызовы.

И еще:

Рассказ JavaScript маленький расширение на язык JavaScript что позволяет блокировать возможности для асинхронные обратные вызовы событий. это делает асинхронный код освежающе читаемый и понятный.

Хотя технически возможно сделать так, чтобы обычно асинхронный код вел себя синхронно, я бы порекомендовал вам пересмотреть свой проект, чтобы использовать асинхронный подход.

0 голосов
/ 06 февраля 2009

Есть ли способ, которым я могу заставить первую функцию JavaScript спать, пока что-то не произойдет (без блокировки браузера)?

То, как вы ожидаете, что это сработает, нет.

AFAIK, требуется управление потоками или непрерывный цикл - первый недоступен в JavaScript, а второй блокирует большинство браузеров.

Я думаю, что вам нужно, чтобы JavaScript отправлял result на сервер с Ajax (из some-async-function-complete). Затем разбейте ваш C #, чтобы один вызов части myscript, а другой отвечали и обрабатывали result.

0 голосов
/ 06 февраля 2009

Возможно, вы думаете о своем приложении как о настольном приложении. Ваша программа на C # не связана с чем-то, с чем нужно работать синхронно. Время перехода фазы в веб-режим.

Самое близкое, что вы можете получить, это вызвать обратный вызов javascript ajax для другого обмена с хостом.

0 голосов
/ 06 февраля 2009

Если я правильно читаю вопрос, вы ищете ответный звонок ... так, например ...

function myscript()
{
    some-async-function(
        params, //any params you plan to use
        function(result) {
           //handle the result here
        });
}

function some-async-function(retval,callback)
{
    //assuming this really is an async function such
    //as an ajax call, etc...
    ...

    //work done, use the call back
    callback(retval);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...