A
A
Alexander Tumaykin2016-03-03 16:03:44
MySQL
Alexander Tumaykin, 2016-03-03 16:03:44

How to make a request synchronous?

I am learning Node and decided to start with koa.
Now I'm trying to solve the following problem: I need to implement the import of the xlsx file into the database.
I implemented the loading and reading of the file, during the import process, you need to add data validation through the add. queries to the database and this is where the difficulty arises. I can not figure out how to make queries to the database pseudo-synchronous.
Those. step by step, I get the following:
1. the file is uploaded to the server
2. the file is read
3. the function for validation is called through array.map for each entry from the file
4. inside the validation function, you need to make a request to the database, after which the validation should be continued. And in this place there is a snag, because. the query to the database is executed after the execution of the main code.
Code example:

function *importExcel() {
  // https://github.com/cojs/busboy
  const parse = require('co-busboy');
  const fs = require('fs');
  const path = require('path');
  const config = require('../../config/path');
  const xlsx = require('xlsx');

  // multipart upload
  let parts = parse(this, {
    checkFile: function (fieldname, file, filename) {
      let ext = path.extname(filename);

      if (ext !== '.xlsx' && ext !== '.xlsm') {
        let err = new Error('Файл должен иметь расширение xlsx либо xlsm');
        err.status = 400;
        return err;
      }
    }
  });

  let part = yield parts;
  let stream = fs.createWriteStream(path.join(config.tmp, Math.random().toString()));
  part.pipe(stream);

  let workBook = yield function (done) {
    stream.on('close', function () {
      try {
        let workBook = xlsx.readFileSync(stream.path);
        done(null, workBook);
      } catch (err) {
        done(err);
      }
    });
  };

  let sheetName = workBook.SheetNames[0];
  let workSheet = workBook.Sheets[sheetName];

  let rows = xlsx.utils.sheet_to_json(workSheet);

  if (rows.length == 0) {
    throw new Error('Импортируемый файл пуст');
  }

  let messages = rows.map((item) => {
    if (Object.keys(item).length > 1) {
      try {
        // ВЫЗОВ ФУНКЦИИ ДЛЯ ПРОВЕРКИ ДАННЫХ В СТРОКЕ ФАЙЛА
        return validateForImport(item);
      } catch (err) {
        return err.message;
      }
    }
    return true;
  }).filter((item) => item !== true);

  this.body = {
    success: true,
    error: messages,
  };

  this.type = 'application/json';
}

/**
 * Валидация для импорта
 *
 * @param data
 * @returns {boolean}
 */
function validateForImport(data) {
  const requiredFields = ['#', 'CID', 'PID', 'Производитель', 'Модель', 'Тип оборудования'];

  requiredFields.forEach((field) => {
    if (data[field] == undefined) {
      let index = field !== '#' ? data['#'] + ': ' : '';
      throw new Error(index + 'колонка "' + field + '" не заполнена');
    }
  });

  let keys = Object.keys(data);
  keys.forEach((field) => {
    data[field] = data[field].trim();
  });
  
  let deviceType;
  // в этом месте нужно сделать запрос к БД и после его выполнения продолжить дальше выполнять функцию
  // выдает ошибку: <b>SyntaxError: Unexpected strict mode reserved word</b>
  // let deviceType = yield db.type.findOne({where: {name: data['Тип оборудования']}});

  // в этом случае данные из БД приходят после отдачи ответа в браузер
  // co(function*() {
  //   return yield db.type.findOne({where: {name: data['Тип оборудования']}});
  // }).then(function (value) {
  //   console.log(value);
  // });

  if (!deviceType) {
    throw new Error(data['#'] + ': тип обородувания "' + data['Тип оборудования'] + '" не найден');
  }

}

Please tell me the best way to solve this problem.
ps uses koa framework and sequelizer to work with mysql

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexander Tumaykin, 2016-03-04
@alexandrtumaykin

Thanks everyone for the advice. A suitable solution turned out to be to abandon Array.map and use for to iterate over the elements of the array.

C
Cat Scientist, 2016-03-03
@eruditecat

Please study Promisehere and here . Feel free to delve into it inside and out. Most likely, this tool will solve your problem in the bud.

I
Ilya Erokhin, 2016-03-04
@AirWorker

I didn't go deep into the code, but
This is where you try to use a generator in a non-generator function:
Must be at least
In general, in koa everything is simple:
* do something
var result = yield do something pluggable
* do something
When we call something with yield - inside this something we can also call something via yield

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question