CasperJs then() чака ли излъчени събития в предишната функция?

Просто съм любопитен как CasperJS обработва събития по отношение на стека за повиквания.

Да кажем, че имаме някакъв код:

casper.on('foo', function() {
    this.wait(60000);
    this.echo('foo');
});


casper.start('http://www.stackoverflow.com', function() {
    this.echo('start');
    this.emit('foo');
});


casper.then(function() {
    this.echo('done');
});

casper.run();

Знам, че then() ще чака проверка срещу 3 флага: pendingWait, loadInProgress и navigationRequested. Разпечатването на стека на повикванията показва, че извикването е във функцията start(), така че start() няма да се счита за завършено, докато събитието не приключи? т.е. ще изчака () докато събитието приключи

Тествах това с изчакване от 60 секунди и получих резултата:

start
foo
done

Въпреки че не бях сигурен дали превишаването на определено време за изчакване ще задейства следващия then().


person Kimmy_Tran    schedule 04.01.2015    source източник


Отговори (1)


Трябва да имате предвид кои функции се изпълняват асинхронно. Във вашия случай първите два реда от изхода се отпечатват незабавно, когато страницата е заредена, а done се отпечатва 60 секунди по-късно.

Неща, които трябва да знаете:

  • Всички функции then* и wait* ще вмъкнат стъпка в опашката, но самите те са асинхронни.
  • casper.emit ще потърси регистрирания манипулатор на събития и ще го изпълни незабавно (неасинхронно).
  • casper.echo ще отпечата нещо веднага (неасинхронно).

Редът на събитията е, че в обратното извикване start, което само по себе си е стъпкова функция, събитие се задейства и незабавно се изпълнява. Това изпълнено събитие съдържа wait извикване, което добавя отложена стъпка след текущата (все още сме в start обратно извикване). След това echo се изпълнява и текущата стъпка е завършена. Следващата стъпка започва с изчакване 60 секунди. Тъй като не е предадено обратно извикване към wait, се изпълнява следващата планирана стъпка. Това е последната стъпка, която съдържа echo('done').

Така че строго погледнато then не изчаква изпълнението на събитието от предишната стъпка, но в този случай не е имало прекъсване на контролния поток (обикновено направено чрез setTimeout) и стъпковият процесор на CasperJS е уловил вътрешната wait стъпка.

person Artjom B.    schedule 04.01.2015
comment
Много изчерпателно, благодаря за отговора! Ако замених израза за изчакване с някаква неасинхронна логика, която отне известно време, трябва ли да очаквам същия резултат? Доколкото разбирам, стартиращото обратно извикване завършва, след като завърши последният неасинхронен оператор (дори ако този оператор е в някакво събитие), а then() няма да се изпълни преди тази точка. - person Kimmy_Tran; 05.01.2015
comment
Вашето наблюдение е правилно и изходът ще бъде същият, но времената ще бъдат различни, тъй като изчакването за блокиране сега е преди this.echo('foo'); - person Artjom B.; 05.01.2015