Чтобы увидеть, как это может пойти не так, напечатайте console.log в конце метода.
Что в целом может пойти не так:
- Произвольный заказ.
- printFiles может завершить работу перед печатью файлов.
- Низкая производительность.
Это не всегда неправильно, но часто встречается в стандартных случаях использования.
Как правило, использование forEach приводит ко всем, кроме последнего. Он будет вызывать каждую функцию, не дожидаясь ее, то есть он сообщает всем функциям о запуске, а затем завершает работу, не дожидаясь завершения функций.
import fs from 'fs-promise'
async function printFiles () {
const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'))
for(const file of files)
console.log(await file)
}
printFiles()
Это пример нативного JS, который сохранит порядок, предотвратит преждевременный возврат функции и теоретически сохранит оптимальную производительность.
Это будет:
- Инициируйте параллельное чтение всех файлов.
- Сохраняйте порядок с помощью map для сопоставления имен файлов с обещаниями, которых нужно ждать.
- Дождитесь каждого обещания в порядке, определенном массивом.
С помощью этого решения первый файл будет отображаться, как только он станет доступен, не дожидаясь, пока сначала станут доступны другие.
Он также будет загружать все файлы одновременно, вместо того, чтобы ждать завершения первого, прежде чем можно будет начать чтение второго файла.
Единственный недостаток этого и исходной версии заключается в том, что если одновременно запускается несколько операций чтения, то обрабатывать ошибки труднее из-за того, что за один раз может произойти больше ошибок.
В версиях, которые читают файл за раз, тогда остановится в случае сбоя, не тратя время на попытки прочитать другие файлы. Даже с тщательно продуманной системой отмены может быть трудно избежать сбоя в первом файле, но уже при чтении большинства других файлов.
Производительность не всегда предсказуема. Хотя многие системы будут работать быстрее с параллельным чтением файлов, некоторые предпочтут последовательное. Некоторые из них являются динамическими и могут смещаться под нагрузкой. Оптимизация, предполагающая задержку, не всегда обеспечивает хорошую пропускную способность в условиях сильной конкуренции.
В этом примере также нет обработки ошибок. Если что-то требует, чтобы они были либо успешно показаны, либо не показывались вообще, этого не произойдет.
Рекомендуется поэкспериментировать с console.log на каждом этапе и решениями для чтения поддельных файлов (вместо этого - случайная задержка). Хотя многие решения, кажется, делают то же самое в простых случаях, все они имеют тонкие различия, которые требуют некоторой дополнительной проверки, чтобы избавиться от них.
Используйте этот макет, чтобы понять разницу между решениями:
(async () => {
const start = +new Date();
const mock = () => {
return {
fs: {readFile: file => new Promise((resolve, reject) => {
// Instead of this just make three files and try each timing arrangement.
// IE, all same, [100, 200, 300], [300, 200, 100], [100, 300, 200], etc.
const time = Math.round(100 + Math.random() * 4900);
console.log(`Read of ${file} started at ${new Date() - start} and will take ${time}ms.`)
setTimeout(() => {
// Bonus material here if random reject instead.
console.log(`Read of ${file} finished, resolving promise at ${new Date() - start}.`);
resolve(file);
}, time);
})},
console: {log: file => console.log(`Console Log of ${file} finished at ${new Date() - start}.`)},
getFilePaths: () => ['A', 'B', 'C', 'D', 'E']
};
};
const printFiles = (({fs, console, getFilePaths}) => {
return async function() {
const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'));
for(const file of files)
console.log(await file);
};
})(mock());
console.log(`Running at ${new Date() - start}`);
await printFiles();
console.log(`Finished running at ${new Date() - start}`);
})();
person
jgmjgm
schedule
14.10.2019
printFiles
функцию высшего порядка, если она не принимает функцию в качестве аргумента или не возвращает функцию в качестве вывода? - person KernelMode   schedule 09.08.2020forEach
является здесь функцией высшего порядка - person Bergi   schedule 09.08.2020