DmitrySheklein
@DmitrySheklein

Как поочерёдно загрузить файлы из API?

Добрый день.
Задача: скачать файлы через API в отдельную папку. Контент файлов отдаётся в base64.

Получается я делаю 1й запрос на получение всего списка текущих файлов по запросу на
http://site.ru/api/v1/site_files/get_list
который возвращает json вида
{
    "status": "ok",
    "data": [{
        "file_id": {
            "type": "int_unsigned_not_null",
            "edit": false,
            "value": "91064166"
        },
        "file_name": {
            "type": "str",
            "edit": true,
            "value": "main.css"
        }
    }]
}

затем делаю в цикле 2й запрос по получению контента каждого файла на
http://site.ru/api/v1/site_files/get/{file_id}
получая json вида
{
    "status": "ok",
    "data": {
        "file_id": {
            "type": "int_unsigned_not_null",
            "edit": false,
            "value": "91064166"
        },
        "file_name": {
            "type": "str",
            "edit": true,
            "value": "main.css"
        },
        "file_content": {
            "type": "blob_base64_encode",
            "edit": true,
            "value": "aHRtbCB7Zm9udC"
        }
    }
}


Код на данный момент написан кустарно через цикл for of, как правильно решается такая задача? Использовать Promise? хотелось, бы загружать файлы поочерёдно...
function download(done) {
	let params = new URLSearchParams();
	params.append('secret_key', SECRET_KEY);

	fetch(`${SITE}/api/v1/site_files/get_list`, {
		method: 'post',
		body:    params,
		timeout: 5000,
	})
	.then(res => res.json())
	.then(json => {
		if(json.status === `ok`) {
		  console.log(`Загружен json ✔️`);  
		  const dir = './download';

		  if (!fs.existsSync(dir)){
			  fs.mkdirSync(dir);
		  }
		
		  const filesArray = json.data.map((item)=>{
			  return {
				file_id: item['file_id']['value'],
				file_name: item['file_name']['value'],
			  }
		  });
		  
		  return filesArray;

		} else if (json.status == `error`) {
		  console.log(`Ошибка загрузки ⛔`);                         
		}
	})
	.then(array =>{
		for (const item of array) {			
			if(item.file_name.includes('css')){		
				let params = new URLSearchParams();
				params.append('secret_key', SECRET_KEY);

				fetch(`${SITE}/api/v1/site_files/get/${item.file_id}`, {
					method: 'post',
					body:    params,
					timeout: 5000,
				})
				.then(res => res.json())
				.then(json => {
					if(json.status === `ok`) {
						const binaryData = new Buffer(json.data.file_content, 'base64').toString('binary');

						fs.writeFile(`./download/${item.file_name}`, binaryData, 'binary', function(err) {
							console.log(err);
						});	
					}	
				})					
			}
		}
	})

	done();
}
  • Вопрос задан
  • 80 просмотров
Решения вопроса 1
bootd
@bootd
Гугли и ты откроешь врата знаний!
Создайте массив запросов и используйте Promise.all это позволит вам загрузить все ваши файлы параллельно, а после обработать все файлы
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@loonny
А зачем вы вот это делаете?
const binaryData = new Buffer(json.data.file_content, 'base64').toString('binary');


Просто записывайте сразу в base64, а если хотите поочередно, но используйте writeFileSync вместо writeFile
fs.writeFileSync(`./download/${item.file_name}`, json.data.file_content, 'base64', function(err) {
  console.log(err);
});
Ответ написан
Ваш ответ на вопрос

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

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