Мне интересно понять, почему использование await
немедленно блокирует, а не лениво блокирует только после обращения к значению await
ed.
Я надеюсь, что это важный / важный вопрос, но я боюсь, что он может быть рассмотрен за пределами этого сайта - если это так, я извинюсь, немного поплачу и возьму вопрос в другом месте.
например. учитывать следующее:
let delayedValue = (value, ms=1000) => {
return new Promise(resolve => {
setTimeout(() => resolve(val), ms);
});
};
(async () => {
let value = await delayedValue('val');
console.log('After await');
})();
В анонимной асинхронной функции, которая запускается немедленно, мы увидим, как консоль произнесет After await
после задержки. Почему это необходимо? Учитывая, что нам не нужно разрешать value
, почему разработчики языка не решили сразу выполнить оператор console.log
в таком случае, как этот?
Например, в отличие от следующего примера, где задержка console.log
, очевидно, неизбежна (поскольку на значение await
ed ссылается):
(async () => {
let value = await delayedValue('val');
console.log('After await: ' + value);
});
Я вижу массу преимуществ для отложенной блокировки await
- это может привести к автоматическому распараллеливанию несвязанных операций. Например. если я захочу прочитать два файла и затем поработать с ними обоими, и я не буду старательным, я напишу следующее:
(async() => {
let file1 = await readFile('file1dir');
let file2 = await readFile('file2dir');
// ... do things with `file1` and `file2` ...
});
Это будет ждать, чтобы прочитать 1-й файл, прежде чем начать читать 2-й. Но на самом деле их можно читать параллельно, и javascript должен уметь обнаруживать это, потому что на file1
не ссылаются до позднего времени. Когда я впервые изучал async / await, я ожидал, что код, подобный приведенному выше, приведет к параллельным операциям, и я был немного разочарован, когда это оказалось ложным.
Параллельно читать два файла все еще немного грязно, даже в этом прекрасном мире ES7, потому что await
блокирует сразу, а не лениво. Вам нужно сделать что-то вроде следующего (что, безусловно, сложнее, чем выше):
(async() => {
let [ read1, read2] = [ readFile('file1dir'), readFile('file2dir') ];
let [ file1, file2 ] = [ await read1, await read2];
// ... do things with `file1` and `file2` ...
});
Почему разработчики языка выбрали блокировку await
немедленно, а не лениво?
например. Может ли это привести к трудностям отладки? Было бы слишком сложно интегрировать lazy await
s в javascript? Есть ли ситуации, о которых я не задумывался, когда ленивые await
приводят к более сложному коду, снижению производительности или другим негативным последствиям?