Подсчет экземпляров случая ошибки в узле / JavaScript MySQL callback

Может ли кто-нибудь сказать мне, почему countDupsвсегда разъясняет0, и назначение countDups += 1;в обратном mySQLCallbackвызове не уважается?

Где я должен использоватьconsole.log(countDups), чтобы получить количество раз ошибка 'ER_DUP_ENTRY'была выдана?

Я пробовал все позиции в коде и объявлял переменную countDupsвнутри / снаружи каждой функции.

Я понимаю, что могу console.log(countDups)внутри .eachцикла , и распечатать каждое приращение — но меня интересует только конечное значениеcountDups, а не значение на каждой итерации. [Спасибо Svabael]

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

'use strict';

const url = require('url'),
fs = require('fs'),
cheerio = require('cheerio'),
moment = require('moment'),
mysql = require('mysql'),
request = require('request');

var connection = mysql.createConnection({
  host     : 'host',
  user     : 'user',
  password : 'pass',
  database : 'db'
});


var opt = {
    url: "http://www.google.co.uk/",   
    json: "",
    credentials: "",
    method: 'GET'
};


var countDups = 0;


var mySQLCallback = function(err, rows, fields) {

    if (err && err.code == 'ER_DUP_ENTRY'){

        countDups += 1;

        return;

      }
 };

request(opt, function(err, response, body) {

    if(err) {
        console.log(err);
    }

    var $ = cheerio.load(body);

    var tds = $('element');

    tds.each(function(){

        if (err) throw err;

        var type = $(this);

        var typeObj = {TYPE:type};

        connection.query('INSERT INTO TABLE SET ?', urlObj , mySQLCallback);

    });



    connection.end();

    console.log(countDups);



});

1 ответ

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

    Редактировать
    Определенно есть более элегантные способы сделать это. В этом случае я использовал переменную, которая играет роль семафора. На каждом tds.на каждой итерации мы увеличиваем var и каждый раз, когда у нас есть ответ на запрос, мы уменьшаем его. Когда она будет равна нулю, это значит, что мы можем спокойно вернуть результаты.

    'use strict';
    
    const url = require('url'),
      fs = require('fs'),
      cheerio = require('cheerio'),
      moment = require('moment'),
      mysql = require('mysql'),
      request = require('request');
    
    var connection = mysql.createConnection({
      host: 'host',
      user: 'user',
      password: 'pass',
      database: 'db'
    });
    
    var opt = {
      url: "http://www.google.co.uk/",
      json: "",
      credentials: "",
      method: 'GET'
    };
    
    var countDups = 0;
    
    function getLastCount (countDups) {
      console.log(countDups);
    }
    
    request(opt, function (err, response, body) {
      if (err) {
        console.log(err);
      }
    
      var $ = cheerio.load(body);
    
      var tds = $('element');
      var i = 0;
    
      tds.each(function () {
        if (err) { 
          throw err;
        }
    
        i++;
    
        var type = $(this);
    
        var typeObj = { TYPE: type };
    
        connection.query('INSERT INTO TABLE SET ?', urlObj, function (err, rows, fields) {
          if (err && err.code == 'ER_DUP_ENTRY') {
            countDups += 1;
            console.log(countDups);
          }
    
          i--;
    
          if (i === 0) {
            getLastCount(countDups);
          }
    
        });
      });
    
      connection.end();
    });