JavaScript: асинхронная функция, которая возвращается к синхронной - PullRequest
1 голос
/ 13 февраля 2012

У меня большой сценарий, который очень синхронный.

1) он выполняет такую ​​функцию:

var result = doSomethingSynchronous(myVar);
if (result === 'something') {
  doSomethingElse();
}

функция doSomethingSynchronous имеет цикл for, который возвращает значение вОператор if:

var i = 0; len = someVariable.length;
for (; i < len; i++) {
  if (someVariable[i] === 'aString') {
    return true;
  } else {
    doSomethingElse();
  }
}

Поскольку цикл for и обработка могут быть интенсивными, я заменил цикл for функцией итеративной обработки очереди, которая запускается сама по себе с использованием setTimeout после перемещения одного элемента из массива.Разумеется, если он выполняется асинхронно, он не возвращает значение и назначает его переменной 'result' в первом фрагменте синхронно, а оператор if всегда завершается неудачей.У меня вопрос, есть ли способ сохранить эту часть синхронной?Нужно ли присваивать значение результату до того, как скрипт перейдет к следующей строке?Или мне необходимо использовать шаблон наблюдателя / посредника или аналогичный для уведомления о завершении асинхронной функции?

В качестве альтернативы я мог бы использовать обратный вызов, но реальный реальный код длиннее, чем этот, и все зависят отсинхронность.Таким образом, переключение var result = doSomethingSynchronous () на асинхронный будет иметь эффект домино на остальных синхронных сценариях, верно?:-) Это звучит как трудное и подверженное ошибкам преобразование, поэтому я подумал, что я бы попросил совета.

Спасибо!

- UDPATED для исправления имени переменной "le".Должно быть "len"

1 Ответ

0 голосов
/ 13 февраля 2012

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

function doSomething(someVariable, callback){
  var i = 0; len = someVariable.length;
  for (; i < len; i++) {
    if (someVariable[i] === 'aString') {
      callback && callback(true);
      break;
    } else {
      setTimeout(function(){ deferredSomething(callback); }, 10);
    }
  }
}

function deferredSomething(callback){
  /* code.. */
  callback && callback('something');
}

doSomething(myVar, function(result){
  if (result === 'something') {
    doSomethingElse();
  }
});

Я также упомяну, что если вы делаете что-то интенсивное, вам определенно следует обратить внимание на веб-работников, чтобы вы могли перенести их в фоновый поток, особенно если вы работаете только с надстройкой FireFox. https://developer.mozilla.org/En/Using_web_workers

- ОБНОВЛЕНО, ЧТОБЫ ИСПРАВИТЬ ПРИМЕР КОДА (фиксированная переменная "le", должна быть "len")

...