Подождите, пока не произойдет событие в функции в Javascript для Skulpt

Я хочу изменить Sk.inputfun() для Skulpt, чтобы позволить пользователю ввести <textarea> и ударил ENTER ключ для отправки. Мне нужно передать единственную функцию в Skulpt, которая получает пользовательский ввод, однако я не могу найти никакого способа сделать это, кроме prompt(),

Единственный способ, которым я мог подумать, это задержать возврат, используя setTimeout() пока событие не вызвало кнопку ввода и не изменило флаг.

var enterPressed = false;
$("#output").keyup(function(e){
    if((e.keyCode || e.which) == 13) { //Enter keycode
      enterPressed = true;
    }
});

а потом ждать изменения у меня было:

 Sk.configure({
    inputfun: function (prompt) {
       function checkFlag() {
          if(enterPressed) {
             enterPressed = false
             return $('#output').val();
          } else {
             window.setTimeout(checkFlag, 100);
          }
       }
       return checkFlag();
    },
    inputfunTakesPrompt: true,
    output: outf,
    read: builtinRead
 });

Однако это не работает по нескольким причинам. а) функция тайм-аута не может вернуть значение, и б) тайм-аут даже не задерживает функцию возврата, и она просто ничего не возвращает.

Я пытался использовать .done() но не смог заставить его работать.

Кажется, нет никакого способа сделать это, что я мог бы найти в Интернете, любая помощь будет высоко ценится!

1 ответ

Решение

Вам необходимо вернуть Promise из вашего inputfun, который вы затем разрешаете, когда нажмете return. (Если вы не знакомы с Promises, их стоит посмотреть - позволяют вам писать асинхронный код с использованием синхронной логики).

Примерно так (используя ваш код в качестве основы):

Sk.configure({
   inputfun: function () {
      // the function returns a promise to give a result back later...
      return new Promise(function(resolve,reject){
         $("#input").on("keyup",function(e){
             if (e.keyCode == 13)
             {
                 // remove keyup handler from #output
                 $("#input").off("keyup");
                 // resolve the promise with the value of the input field
                 resolve($("#input").val());
             }
         })
      })
   },
   output: outf,
   read: builtinRead
});

Я предположил, что элемент ввода с идентификатором ввода получает стандартный ввод. Глядя на ваш OP, вы говорили о текстовой области (хотя JQuery .val() должен работать нормально). Исходя из того, что вы назвали своей текстовой областью ("выходные данные"), кажется, что вы хотели, чтобы и stdin, и stdout использовали общую текстовую область. Если это так, я не уверен, как вы сможете отличить то, что было сгенерировано с помощью stdin, и то, что было (впоследствии) введено пользователем. Таким образом, код выше предполагает отдельное поле ввода.

У меня был похожий сценарий использования, и у меня была иллюзия интегрированной консоли как для stdin, так и для stdout, заключалась в том, чтобы в конце моего выходного div иметь span с contenteditable. В коде ключа == 13, прежде чем я разрешил обещание и отправил обратно то, что набрал пользователь, я вынул текст из диапазона ввода и добавил его к выходному элементу div.

Другие вопросы по тегам