2014-12-26 2 views
1

Обновление: Это оказалось действительно глупым вопросом. Я просто не заметил некоторых простых вещей в цитируемом примере.Пожалуйста, объясните пример в документации NextTick

Я искал информацию о тиках и цикле событий, и в основном это ясно, но есть пример в the nextTick documentation, который меня озадачивает. В нем говорится:

Очень важно, чтобы API-интерфейсы были либо 100% синхронными, либо 100% асинхронными. Рассмотрим этот пример:

// WARNING! DO NOT USE! BAD UNSAFE HAZARD! 
function maybeSync(arg, cb) { 
    if (arg) { 
    cb(); 
    return; 
    } 

    fs.stat('file', cb); 
} 

Этот API опасен. Если вы это сделаете:

maybeSync(true, function() { 
    foo(); 
}); 
bar(); 

Тогда неясно, будут ли сначала вызваны foo() или bar().

Первые вопросы: почему является Foo не гарантированно будет называться первым? Существует простой вызов функции (возможно, Sync), , если, и обратный вызов cb = foo. Я полагаю, что что-то в этой цепочке каким-то образом (возможно) асинхронно, толкает что-то в очередь событий и продолжает выполнение? Я не вижу, как бы там ни было.

Второй вопрос: есть ли где-то документация, которая могла бы помочь мне понять это самостоятельно?

ответ

1

Это довольно просто. foo будет гарантированно называться первым, если его нет arg, так же как и foo будет гарантированно назван последним, если есть arg. Только представьте себе, стеки вызовов здесь:

arg существует

  • maybeSync называет cb сразу же в итерации цикла обработки событий. foo называется синхронно, а в то же событийного итерации цикла
  • maybeSync возвращается - так fs.stat никогда не вызывается в этом случае
  • bar вызывается после foo делается

arg не существует

  • возможноSync вызывает fs.stat (что является асинхронным), предоставляя cb в качестве callbac К
  • нет более синхронного кода для запуска в текущей итерации событий петли таким образом bar называется
  • fs.stat завершен, и он вызывает cb на следующей итерации цикла событий (после bar).foo выполняется синхронно, но в течение еще одной итерации цикла событий на этот раз

Оба варианта очевидны. Проблема в том, что в большинстве случаев вы не знаете заранее, есть ли значение arg (в противном случае нет необходимости в if :)), поэтому у вас может быть два сценария запуска этого кода, что усложняет ситуацию.

process.nextTick подражает ASync природа fs.stat здесь, так что foo является всегда называется на следующем цикле обработки событий итерации делает поток предсказуем.

+1

Хм, я смущен несколькими вещами в этом ответе: 1. Вы перевернули «foo не существует»/«foo существует»? Его нельзя назвать, если он не существует, не так ли? 2. Почему fs.stat вызывается только в одном из случаев? 3. Вы, кажется, говорите, что foo всегда вызывается перед баром, если foo называется вообще. Итак, я не понимаю, что неясно в коде, т. Е. В чем смысл примера. – njlarsson

+0

1. Woops, извините - я имел в виду 'arg' здесь. 2. Есть инструкция 'return', поэтому' fs.stat' не будет вызываться, если вы предоставите 'arg'. 3. 'foo' ** всегда вызывается **, потому что' cb' всегда вызывается. Разница между этими двумя примерами - это просто порядок вызовов 'foo' и' bar'. –

+0

А, ок, так что это только двойной случай слепоты с временным кодом с моей стороны: почему-то я не заметил, что оператор возврата (уродливый! Должен был быть if-else по-моему), а параметр «cb» для fs. стат. Благодарю. – njlarsson

Смежные вопросы