Использование класса External Wait для приостановки выполнения функций javascript

Я пытаюсь понять, как приостановить выполнение функции перед вызовом другой функции, делая мой код javascript чрезвычайно читаемым. Вот пример того, что я пытаюсь сделать:

function main_function(){   
   function a();
   // wait for function a to finish - could take 1 second - could take 3 seconds

   function b();
   // wait for function b to finish - don't know how long this will take

   function c();
   // completed
}

Я прочитал десятки статей о том, как использовать setTimeOut, перенаправления на другие функции, обратные вызовы и т. д., но не смог найти решение, которое действительно работало бы хорошо (и в большинстве из них просто используется неуклюжий setTimeout(), который на самом деле не работает). помогите, так как я понятия не имею, сколько времени может занять каждая функция).

Итак, я наконец-то наткнулся на небольшую утилиту под названием «WaitThread.js». Кажется, это именно то, что мне нужно сделать, и кажется, что это будет что-то, что легко читать и поддерживать позже.

Однако я не могу понять, как его использовать! :)

Кто-нибудь может предоставить мне пример того, как использовать этот WaitThread.js? Или, по крайней мере, предоставьте мне удобочитаемый/элегантный способ ожидания выполнения функций javascript одна за другой, ожидая, пока каждая из них завершится первой?

Вот ссылка на страницу WaitThread.js:

http://www.robertmayo.com/blog/2006/07/htmljavascript-wait-for-asynchronous.html

Спасибо!


person swhitlow    schedule 02.07.2011    source источник
comment
Это решение действительно не волшебное или что-то в этом роде. Все, что он делает, это опрашивает сторожевой таймер на наличие изменений в каком-либо состоянии. В веб-браузере нет такой вещи, как ожидание кода JavaScript. Единственный способ решить эту проблему — использовать модель асинхронного программирования.   -  person Pointy    schedule 03.07.2011
comment
Кроме того, было бы полезно предоставить некоторые пояснения и предложения, если бы вы более подробно рассказали о том, что делают эти функции и что заставляет их выполняться долго.   -  person Pointy    schedule 03.07.2011


Ответы (1)


Согласно объяснению для waitthread.js, он просто использует таймер для опроса, ожидая изменения значения некоторой переменной.

Более типичный шаблон проектирования для этого типа проблем использует обратные вызовы, и function a вызовет обратный вызов, когда его работа будет выполнена, что запустит function b. Итак, вы передаете функцию function a, которая должна быть вызвана, когда function a завершит свою работу. Более полный шаблон проектирования обычно имеет обратный вызов как для успешного выхода, так и для неудачного выхода и может даже передавать параметры из выхода, но, поскольку я не знаю ваших особенностей, я не пытался моделировать это здесь. Для многоэтапного процесса это будет выглядеть так. Мы предполагаем, что существуют три асинхронные функции как функции a, b и c, и каждая принимает функцию в качестве аргумента, который будет вызываться, когда асинхронная функция будет завершена:

function main_function_step1() {
  a(main_function_step2);
}

function main_function_step2() {
  // execute code here that goes after function a, but before function b
  b(main_function_step3);
}

function main_function_step3() {
  // execute code here that goes after function b, but before function c
  c(main_function_finish);
}

function main_function_finish()
{
  // execute whatever code here to finish
}

Более полное решение будет передавать объект с обратным вызовом при успешном выполнении и обратным вызовом при отказе, а также предоставить по крайней мере параметр для каждой функции, чтобы можно было вернуть результаты или условия ошибки.

В таком случае это будет выглядеть так:

function main_function_step1() {
  function main_function_a_step1_fail(err)
  {
    // handle error in step 1
  }
  var o = {success: main_function_step2, fail: main_function_a_step1_fail};
  a(o);
}

function main_function_step2(data) {
  // execute code here that goes after function a, but before function b
  function main_function_a_step2_fail(err)
  {
    // handle error in step 2
  }
  var o = {success: main_function_step3, fail: main_function_a_step2_fail};
  b(o);
}

function main_function_step3(data) {
  // execute code here that goes after function b, but before function c
  function main_function_a_step3_fail(err)
  {
    // handle error in step 3
  }
  var o = {success: main_function_finish, fail: main_function_a_step3_fail};
  c(o);
}

function main_function_finish(data)
{
  // execute whatever code here to finish
}

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

person jfriend00    schedule 02.07.2011
comment
jfriend00 - Спасибо за отзыв! Это выглядит неплохо. Тем не менее, это все еще выглядит немного грязно (как вы отметили в своем комментарии). Не могли бы вы предоставить мне пример того, как использовать файл WaitThread.js, чтобы я мог увидеть, как он будет работать, а затем, возможно, позже я мог бы изменить его, чтобы он соответствовал вашей модели, которую вы показали здесь. Спасибо! - person swhitlow; 03.07.2011
comment
Pointy — функция вызывает Java-приложение, которое сканирует удостоверение личности. Пока это происходит, скрипт должен ждать. Когда это будет сделано (т. Е. Когда файл изображения действительно существует), он затем использует другую оболочку javascript вокруг java-апплета, который FTP передает изображение на сервер. После этого он анализирует данные из отсканированной лицензии. Я хорошо знаю PHP и C#. Однако javascript (я бы сказал — продвинутый javascript) для меня немного новинка. Мне потребовалось некоторое время, чтобы осознать тот факт, что я не могу вызвать сценарий и дождаться его выполнения, а затем вызвать следующий сценарий. - person swhitlow; 03.07.2011
comment
Я могу сделать это, если я вызываю вызов ajax (т.е. вызываю файл PHP для выполнения некоторой обработки), однако я не могу сделать это, просто вызывая внутренние функции javascript (один к другому). - person swhitlow; 03.07.2011
comment
Извините, но я не знаю библиотеку waitThread. Я, скорее всего, начну использовать YUI3 AsyncQueue: developer.yahoo.com/yui/3 /async-queue, чтобы сделать этот тип кода более читабельным/поддерживаемым. - person jfriend00; 03.07.2011