2014-12-28 4 views
2

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

Например, код метаязык может выглядеть

1. dosomething(4) 
2. dosomethingelse(1) 
3. dosomething(7) 
4. goto 2 

с функциями, реализованных в JavaScript как

function dosomething(n, callback) { 
    ... // do something with n 
    setTimeout(callback, 1000); 
} 

function dosomethingelse(n, callback) { 
    ... // do something else with n 
    setTimeout(callback, 1000); 
} 

Без goto заявления, это было бы легко компилировать яваскрипт и затем eval. Тем не менее, я не знаю, как реализовать goto. Любая помощь приветствуется.

+0

безусловный переход только в цикле while – akonsu

+0

как вы интерпретируете цикл блокировки while на неблокируемом языке? – twinlakes

+0

Я не понимаю этот вопрос. – akonsu

ответ

2

Как уже говорили, ознакомьтесь с обещаниями. Этот учебник действительно помог мне начать работу с ними, надеюсь, это тоже поможет вам. https://spring.io/understanding/javascript-promises

1

Используйте yield, чтобы функции, которые вы можете сделать паузу, а затем regenerator, чтобы запустить его в старых браузерах:

Во-первых, мы преобразуем dosomething(4) на вашем языке в:

function doSomething(n, callback){ 
    setTimeout(function(){ callback(null,true); }, n); 
} 

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

Тогда - вы можете конвертировать их обещаниям легко:

var doSomething = Promise.promisify(doSomething); // using bluebird. 

Теперь, когда они возвращаются promises- вы можете обернуть линии с yield с:

Promise.coroutine(function*(){ 
    yield dosomething(4); 
    yield dosomethingelse(1); 
    yield dosomething(7); 
}); 

Вам нужно будет позвонить в addYieldHandler чтобы иметь дело с полученными обезличиваемыми значениями. Это выполнит их «синхронно», ожидая разрешения каждого обещания до начала следующего. Наконец, используйте регенератор, чтобы преобразовать ваш код во что-то, что может запускать браузер ES5 (так как yield работает только в FF и в Chrome под флагом atm).

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