Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.09.2020, 11:17
Новичок на форуме
Отправить личное сообщение для Alesei Посмотреть профиль Найти все сообщения от Alesei
 
Регистрация: 02.09.2020
Сообщений: 1

Проблема с использованием промисов
Всем здравствуйте.
Возникла проблема с работой цикла в функции, из-за асинхронного его выполнения.
Изначально я его сделал на XMLHttpReuqest, где принудительно указывал запрет на асинхронность параметром false, но потребовалось переделать на fetch, и тут у меня возникли проблемы, как я понимаю мне надо все переделать на промисы .then, но что-то я не догоняю как правильно это сделать.
Не пинайте сильно, это мой первый код не только на js, а в принципе.
https://learn.javascript.ru/promise-basics <- данную статью читал, и не вкурил совсем.


const express = require('express');
const fetch = require('node-fetch');
const app = express();
const port = 3000;
const excel = require('exceljs');
const workbook = new excel.Workbook();

//Заносим в опцию токен для Синтека
const options = {
    headers: {
        ZakupayToken: '***'
    }
};

//Обновляем справочники
let payers;
let acceptor;
fetch('https://***/api/v1/refbooks/offerPayers?', options)
    .then(response => response.json())
    .then(data => payers = data.payers);
fetch('https://***/api/v1/refbooks/offerAcceptors?', options)
    .then(response => response.json())
    .then(data => acceptor = data.acceptors)
    .then(() => acceptor.splice(0,0,{
        "firstName":"",
        "id":"",
        "lastName":"Любой"        
    }));

//ВЭБ форма нашего микросервиса
app.use(express.static('public'));

app.get('/', (req, res) => {
    const content = `<html><head></head><body>
	<h1>Эн-Системс Синтека БСПБ</h1>
	<h2>Сформировать импорт-файл</h2>
	<form action="/save" method="get">
		Период с: <input type="date" name="dateFrom" />
		по: <input type="date" name="dateTo" /><br><br>
		Плательщик: <select name="payerId">${payers.map((p) => `<option value=${p.id}>${p.shortName}</option>`)}</select><br><br>
		Акцептор: <select name="acceptor">${acceptor.map((p) => `<option value=${p.id}>${p.lastName} ${p.firstName}</option>`)}</select><br><br>
		<input type="submit" value="Сформировать">
    </form>
  </body></html>`;
  res.send(content);
});

app.get('/save', (req, res) => {
	const params = req.query;
	const resp = cynteka(params);
	res.send(resp);
});

app.listen(port, () => {
  console.log(`Example app listening at http://10.1.1.211:${port}`)
});

//Функция формирования импорт-файла для БСПБ
function cynteka({dateFrom, dateTo, payerId, acceptor}) {
	const params = [
		dateFrom ? 'creationDateFrom=' + dateFrom : '',
		dateTo ? 'creationDateTo=' + dateTo : '',
		payerId ? 'payer=' + payerId : '',
		acceptor ? 'acceptor=' + acceptor : '',
		'pageSize=1'
    ].join('&');

    let respBuffer = ''; //Буфер для вывода результата на экран

    let url = 'https://***/api/v1/offers?' + params;

    let count;

    let filename = 'public/import-bspb.xlsx';

    //Создаем пустой эксель и заполняем шапку
	let xlsx = [
		"№ пп", 
		"Несрочный платеж", 
		"Сумма", 
		"ИНН получателя", 
		"Наименование получателя", 
		"Р/сч получателя", 
		"БИК банка получателя", 
		"Код вида дохода", 
		"Назначение платежа",
	];
	workbook.addWorksheet('Лист 1').addRow(xlsx);

    //Запрашиваем количество счетов
    fetch(url, options)
        .then(response => response.json())
        .then(data => count = data.totalCount);

    respBuffer += 'Обработаных счетов: ' + count + '<br>';
    
    //Цикл обработки счетов    
    while (count){
        let offers;
        let nds;

        fetch(url + '&page=' + count, options)
            .then(response => response.json())
            .then(data => offers = data.offers[0]);
    
        if (offers.vat != 0){
            let vat = offers.vat * 100 +"%";
            let vatAmount = (((offers.totalAmount / (1 + offers.vat) ) - offers.totalAmount) * -1).toFixed(2);
            nds = `В том числе НДС ${vat} ${vatAmount} руб.`;
        }else{
            nds = "НДС не облагается";
        };

        try {
		    xlsx = [
			    offers.id, 
			    "нет", 
			    (offers.totalAmount).toFixed(2), 
			    offers.supplier.inn, 
			    offers.supplier.shortName, 
			    offers.destinationAccount.currentAccount, 
			    offers.destinationAccount.bik,
			    ,
			    `Счет ${offers.producerOfferNumber} от ${moment(offers.producerOfferDate).format("DD-MM-YYYY")} ${nds}`,
		    ];
		    workbook.getWorksheet('Лист 1').addRow(xlsx); //Добавлем обработанную строку в эксель
		} catch (err) {
            respBuffer += `Счет №${offers.id}: Ошибка обработки <input type="button" class="button13" value="Открыть в Синтека" onclick="window.open('https://***/core/offers/${offers.id}/report')">` + '<br>';
		};
		
        count--;
        
    };

    workbook.xlsx.writeFile(filename); //Сохраняем эксель файл

	respBuffer += `Импорт-файл для БСПБ готов:` + '<br>';
	respBuffer += `<button onclick="document.location='/import-bspb.xlsx'">Скачать</button> <button onclick="document.location='/'">Назад</button>`;

    return respBuffer;
};
Ответить с цитированием
  #2 (permalink)  
Старый 02.09.2020, 11:37
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Сообщение от Alesei
https://learn.javascript.ru/promise-basics <- данную статью читал, и не вкурил совсем.
попробуй ещё раз.
в учебнике тема дается подробно, и в то же время максимально лаконично.
здесь в топике вряд ли получится рассказать теорию промисов лучше.
Ответить с цитированием
  #3 (permalink)  
Старый 02.09.2020, 13:04
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,737

Чтобы не пришлось пхать html разметку в файлы с логикой придумали шаблонизаторы. Они позволяют вынести представление в отдельный файл.
https://expressjs.com/en/resources/t...e-engines.html
Ответить с цитированием
  #4 (permalink)  
Старый 02.09.2020, 15:44
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,712

Функцию cynteka проще переписать используя async/await


//Функция формирования импорт-файла для БСПБ
async function cynteka({dateFrom, dateTo, payerId, acceptor}) {
    const params = [
        dateFrom ? 'creationDateFrom=' + dateFrom : '',
        dateTo ? 'creationDateTo=' + dateTo : '',
        payerId ? 'payer=' + payerId : '',
        acceptor ? 'acceptor=' + acceptor : '',
        'pageSize=1'
    ].join('&');
 
    let respBuffer = ''; //Буфер для вывода результата на экран
 
    let url = 'https://***/api/v1/offers?' + params;
 
    let count;
 
    let filename = 'public/import-bspb.xlsx';
 
    //Создаем пустой эксель и заполняем шапку
    let xlsx = [
        "№ пп",
        "Несрочный платеж",
        "Сумма",
        "ИНН получателя",
        "Наименование получателя",
        "Р/сч получателя",
        "БИК банка получателя",
        "Код вида дохода",
        "Назначение платежа",
    ];
    workbook.addWorksheet('Лист 1').addRow(xlsx);
 
    //Запрашиваем количество счетов
    let response = await fetch(url, options);
    let data =  await response.json();
    count = data.totalCount;
 
    respBuffer += 'Обработаных счетов: ' + count + '<br>';
     
    //Цикл обработки счетов   
    while (count){
        let nds;
 
        let response = await fetch(url + '&page=' + count, options)
        let data =  await response.json()
        let offers = data.offers[0];
     
        if (offers.vat != 0){
            let vat = offers.vat * 100 +"%";
            let vatAmount = (((offers.totalAmount / (1 + offers.vat) ) - offers.totalAmount) * -1).toFixed(2);
            nds = `В том числе НДС ${vat} ${vatAmount} руб.`;
        }else{
            nds = "НДС не облагается";
        };
 
        try {
            xlsx = [
                offers.id,
                "нет",
                (offers.totalAmount).toFixed(2),
                offers.supplier.inn,
                offers.supplier.shortName,
                offers.destinationAccount.currentAccount,
                offers.destinationAccount.bik,
                ,
                `Счет ${offers.producerOfferNumber} от ${moment(offers.producerOfferDate).format("DD-MM-YYYY")} ${nds}`,
            ];
            workbook.getWorksheet('Лист 1').addRow(xlsx); //Добавлем обработанную строку в эксель
        } catch (err) {
            respBuffer += `Счет №${offers.id}: Ошибка обработки <input type="button" class="button13" value="Открыть в Синтека" onclick="window.open('https://***/core/offers/${offers.id}/report')">` + '<br>';
        };
         
        count--;
         
    };
 
    workbook.xlsx.writeFile(filename); //Сохраняем эксель файл
 
    respBuffer += `Импорт-файл для БСПБ готов:` + '<br>';
    respBuffer += `<button onclick="document.location='/import-bspb.xlsx'">Скачать</button> <button onclick="document.location='/'">Назад</button>`;
 
    return respBuffer;
};


Вызывать ее
let rspb = await cynteka({...})
или
cynteka({...}).then ((rspb) => {...})
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Смена background при нажатии JIeuTo Общие вопросы Javascript 5 14.09.2018 18:48
Выполнение массива промисов последовательно arealhz Node.JS 30 07.07.2018 12:45
Проблема с радио кнопками px379 Общие вопросы Javascript 8 29.07.2013 09:30
проблема с использованием JSBuilder3 nikolaich ExtJS 2 19.04.2012 13:23
Проблема с дизайном после отправки xmlhttprequest, Проблема с дизайном после отправки cyberx AJAX и COMET 3 01.05.2010 17:07