2013-04-16 4 views
4

Возможно, что мой код может отложить две или более функции в короткие последовательности. Могу ли я гарантировать, что каждая отложенная функция будет выполняться в том порядке, в котором я их создал? Для моего веб-приложения на iOS 5 & 6 правильность моего кода основана на отложенных функциях, выполняемых по порядку.В Javascript, отложенные функции выполняются в порядке?

Я использую Prototype's defer, который реализован с использованием тайм-аута 0,01 секунды.

Функция «отложенная» не запускается немедленно; скорее, он будет работать как в скором времени, когда стек вызовов интерпретатора пуст.

Из моего собственного тестирования кажется, что они выполняются в том порядке, в котором я их создаю. Далее были напечатаны все целые числа от 0 до 99.

Код проверки

for (var i = 0; i < 100; i++) { 
    (function(x) { 
     return function() { 
      console.info(x); 
     } 
    })(i).defer(); 
} 

Выход

0 
1 
2 
... 
88 
99 

Однако этот результат не является окончательным. Я понятия не имею, как он ведет себя с более глубокими функциями или разными нагрузками на ЦП.

+1

Почему бы не программа, как будто не было никакой гарантии? – akonsu

+0

в методе 'defer()' он вызывает метод 'delay()', который использует собственный 'setTimeout()'. Почему бы не использовать пользовательские прослушиватели событий? т.е. 'document.observe ('trigger: myfirstevent', function() {});' then' document.fire ('trigger: myfirstevent'); 'пока вы откладываете первый вызов, остальные вызовы будут срабатывать заказ. (Пользовательские события требуют пространства имен с использованием «:») –

+0

@akonsu Я обнаружил, что обработка событий JS iOS выполняется в другом потоке, чем в основном потоке. В многопоточной среде любая функция может быть отключена на полпути, а другой код будет выполнен. Код перемежения вызовет проблемы конечного автомата для тех, кто привык к традиционному однопоточному двигателю JS. Чтобы облегчить эти проблемы, я хотел отложить обработку обратных вызовов обработки событий для имитации однопоточного кодирования кода. – Pwner

ответ

0

Prototype.js's defer() использует setTimeout() в качестве его кода подписи.

function delay(timeout) { 
    var __method = this, args = slice.call(arguments, 1); 
    timeout = timeout * 1000; 
    return window.setTimeout(function() { 
      return __method.apply(__method, args); 
    }, timeout); 
} 

//This calls Prototype's delay() function above (which calls setTimeout) 
function defer() { 
    var args = update([0.01], arguments); 
    return this.delay.apply(this, args); 
} 

spec для SetTimeout говорит, что порядок гарантирован. Тем не менее, многие люди заявили, что их функции были выполнены не по порядку, поэтому разные браузеры могут не все правильно реализовать спецификацию. Я бы предположил, что заказ не гарантирован.

Вместо этого вы должны объединить свои функции. Итак, сделайте что-нибудь вроде:

var funcsToRun = []; 
var currFunc = 0; 

//Add the functions 
for (var i = 0; i < 100; i++) 
{ 
    funcsToRun.push(function(x) { 
     return function() { 
      console.info(x); 
     } 
    ); 
} 

//This will chain the execution; 
function chain() 
{ 
    //RUn current function 
    funcsToRun[ currFunc ](currFunc++); 

    //Now do next one if needed 
    if (currFunc < funcsToRun.length) chain(); 
} 

setTimeout(chain, 10); 
Смежные вопросы