2016-11-01 2 views
-2

Я разрабатываю проект для создания визуализации в d3. У меня есть массив, который имеет имена файлов, которые должны быть загружены последовательно.Javascript - Async

Но при запуске массива и вызове соответствующих методов второй элемент массива называется намного до того, как первый из них даже закончил загрузку.

 for(j=0;j<chosenAirports.length;j++) 
     { 
      var fileName = chosenAirports[j]; 
      var splitData = fileName.split("_");     
      readFile(splitData[0],selectedYear,splitData[0] + "_" + selectedYear); 
     } 

readFile - это функция, которую я пытаюсь вызвать для каждого из элементов массива. Но до того, как readFile для одного элемента будет завершен, следующий вызов в цикле будет вызван.

И я считаю, что это связано с асинхронной функцией javascript. Может ли кто-нибудь предложить метод, с помощью которого я могу избежать этого.

Любая помощь приветствуется.

+0

Поскольку вы пошли вперед и испортили все наши головы, используя имя 'readFile()', можем ли мы увидеть, что на самом деле делает ваш 'readFile()'? Мы не можем делать какие-либо предположения или предоставлять помощь, если функция является черным ящиком без каких-либо подробностей ввода, вывода или того, что она делает внутри. – gelliott181

ответ

0

Учитывая, что вы читаете файл, я думаю, что это работает на узле?

Если это так, то функция readFile либо вызов readFile функции узла или являетсяreadFile функции узла.

Как вы заявили, это асинхронная функция. Существует синхронная версия, которая называется readFileSync, которая предотвратит проблему, которую вы видите.

0

Если вы хотите, чтобы код работал, использование синхронного метода readFileSync() исправит вашу проблему (подробнее здесь: https://code-maven.com/reading-a-file-with-nodejs).

Если вы заинтересованы в том, чтобы асинхронные функции возвращались, но все же выполнялись асинхронно, вам может быть интересно работать с RxJS Promises.

+0

Боюсь, я провожу вас всех в неправильном направлении.ReadFile не поддерживает чтение из файла. Это просто имя функции, которая выполняет определенную задачу (ничего не связано с файлами). Извините, что не предоставил полную информацию. – Minu

0

Если вы хотите оставаться асинхронным - и я предлагаю вам делать то, что вам не нужно бороться с тем, что является ядром для Node/Javascript, - вы можете обернуть обработку файла внутри Promise: создать функцию, которая принимает имя файла в качестве параметра, и который возвращает обещание с результатом обработки.

Что-то вроде:

function processFile(fileName) { 
    return new Promise((resolve,reject) => { 
    fs.readFile(fileName, function(err, data){ 
     if (err) { 
     return reject(err); 
     }; 
     return resolve(processData(data)); 
    }); 
    }); 
} 

Очевидно, что вам нужно будет обеспечить вашу processData() функции и убедитесь, что она возвращает данные для обработки данного файла.

Затем к цепочке обработки всех файлов в порядке, вы можете использовать метод reduce в массиве как:

const promise = chosenAirports.reduce((promise, fileName) => { 
    return promise.then((previousResult) => { 
    return processFile(fileName); 
    }) 
}, Promise.resolve()); 

Тогда вы запрашиваете результат этого обещания, чтобы получить окончательный результат.

promise 
.then((result) => { 
    console.log('Result: ', result); 
}) 
.catch((err) => { 
    console.log(err); 
}); 

Это, чтобы использовать для обработки данных и реализовать механизм сбора всех результатов, но не трудно с этим решением.