Чтение файлов по одному и вызов api только после вызова первого файла

#javascript #node.js #express #promise

#javascript #node.js #экспресс #обещание

Вопрос:

Вот мой код, который будет считывать файлы один за другим и отображать их содержимое, и он вернется, как только все файлы будут прочитаны.

Здесь я хочу вызывать api всякий раз, когда 1 файл прочитан полностью

Вот пример содержимого 3 файлов. Не учитывайте, что весь файл будет иметь filenumber.txt . это просто пример

 **1.txt**
_____
1-one
1-two
1-three
_____
**2.txt**
_____
2-one
2-two
2-three
_____
**3.txt**
_____
3-one
3-two
3-three
  

Вот мой маршрутизатор для чтения и отображения всего текста

 var express = require('express');
var router = express.Router();
var fs = require('fs');


var arr = [];

router.get('/', function(req, res, next) {
  for (let index = 1; index <= 3; index  ) {
    arr.push(readFile('public/file/' index '.txt'));
    console.log(index);
  }
  Promise.all((arr))
  .then(function (results) {
    console.log('done!')
    res.send('respond with a resource');
  });
});
  

функция чтения файла

 function readFile(name){
  return fs.readFile(name, "utf8",function(err, data) {
    console.log(name,data);
  });
}
  

по обещанию Promise.all((arr)) он вернется, как только все файлы будут прочитаны. Отсюда я хочу вызвать API для каждой строки в файле.

Следующий файл должен быть прочитан только после того, как все вызовы api для текущих файлов будут прочитаны.

Вот функция вызова api

 const axios = require('axios');
function doApi(url){
  var url = `https://run.mocky.io/v3/url?prod=${url}`
  var config = { method : 'get', url : url, headers : {}, data : {}};
  return axios(config)
    .then(function (response) {
      console.log('prod',url,response.data)
    }).catch(function(err){
      console.log('err1');
  })
}
  

Примечание :

Это должно быть похоже

Шаг 1: Прочитайте первый файл, прочитанные данные будут похожи

 1-one
1-two
1-three
  

Шаг 2: Теперь вызовите do api

 // These 3 api's can be ran concurrently, but file read should be done one by one only
https://run.mocky.io/v3/url?prod=${1-one}
https://run.mocky.io/v3/url?prod=${1-two}
https://run.mocky.io/v3/url?prod=${1-three}
  

Повторите шаг 1 для второго файла.

Как я могу этого добиться

Ответ №1:

Прочитайте каждый файл 1 на 1 в цикле, инициализируя объекты Promise для обработки doApiCall(), передающего содержимое файла (параметр URL) и добавляющего их в массив Promises.

Когда все файлы прочитаны, проблема Promise.all(promises) .

 router.get('/', (req, res) => {
  let filepaths = ['filepath1', 'filepath2', '...' , 'filepathN'];

  let concurrentAPICalls = [];

  for (let fp of filepaths) {
    let fileContents = readFileSynchro(fp);  // no await

    for (let line of fileContents.split('n')) {
       // initialise promise to issue REST call with url inside file
       concurrentAPICalls.push(new Promise(line).then(doApiCall).catch(apiError)));
    }
  }

  // execute all promises after reading files 1 by 1
  // best effort (don't drop remaining on first failure)
  Promise.allSettled(concurrentAPICalls).then(() => res.send('all files processed'));
});