@9karamba

Как записать данные из асинхронной функции?

Например, есть такая функция
function getFiles(directoryPath, arrFiles, callback) {
    fs.readdir(directoryPath, (err, files) => {
        if (err) console.log(err);
        ... //здесь добавляю в массив файлы
        callback(arrFiles);
    });
});

А здесь я хочу получить данные, но выводит undefined
var file;
getFiles("./",[], function(result){
    file = result;
    return file;
});


Как записать данные в переменную?
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
kshshe
@kshshe
Frontend developer
Поскольку два ответа добавлять нельзя, у этого ответа будет две части.

Часть 1, если нужно решить только эту проблему.

Скорее всего, вы делаете что-то такое:
var file;
getFiles("./",[], function(result){
    file = result;
    return file;
});
console.log(file);

Если да, то это распространенная ошибка тех, кто начинает разбираться с асинхронностью.

Если сделать так, то вот, что будет происходить:

1. Объявилась переменная
var file;

2. "Создай запрос на получение файлов. Когда они будут получены, вызови коллбек" (очень примерно)
getFiles("./",[], function(result){
    file = result;
    return file;
});


3. Выводите file (пустой)
console.log(file);

4. Файлы получены, вызывается коллбек. Return отсюда никуда не попадает.
file = result;
return file;


Как можно сделать

Вариант 1:
getFiles("./",[], function(result){
    var file = result;
    // Дальше работаем с file здесь
});


Вариант 2:
function getFiles(directoryPath) {
    return new Promise((resolve, reject) => {
    	fs.readdir(directoryPath, (err, files) => {
	       let arrFiles = [];
	       // ... Добавляете в arrFiles нужную информацию
               if (err) {
	        	console.log(err);
	        	reject(err);
	        }
	        resolve(arrFiles);
	    });
    })
};

// где-то выше
async function someFunction() { // Функция, где находится var file и остальное
	// ...

	try {
		var file = await getFiles("./"); // Здесь await заставит ваш код "ждать", пока из Promise в getFiles не будет вызван resolve
		console.log(file);
	} catch (e) {
		// Сделать что-то с ошибкой
	}

	// ...
}


Часть 2, если нужно понять, как быть в таких ситуациях в дальнейшем.

Добавьте в свой код перед вызовом getFiles ключевое слово debugger, вот так:
var file;
debugger;
getFiles("./",[], function(result){
    file = result;
    return file;
});

Перед запуском скрипта откройте chrome://inspect. Нажмите на "Open dedicated DevTools for Node".
Запустите скрипт с параметром --inspect, вот так:
node --inspect myScript.js

После запуска скрипт остановится и вы сможете выполнять его постепенно, понимая, где находится ошибка. В дебаггере справа-сверху будет несколько кнопок с разными вариантами переходов, вам нужен "Step", это точка и прямая стрелка вправо. Когда вы будете на нее нажимать, будет выполняться текущая операция и на следующей код снова остановится.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы