Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Nodejs mengungkapkan dan berjanji tidak melakukan apa yang saya harapkan

Masalah dengan kode

Oke, ada banyak masalah di sini jadi hal pertama yang pertama.

        connection.query('...', function (err, rows) {
            connection.release();
            if (!err) {
                return rows;
            } else {
                return false;
            }
        });

Ini tidak akan berfungsi karena Anda mengembalikan data ke pemanggil, yang merupakan kueri basis data yang memanggil panggilan balik Anda dengan err dan rows dan tidak peduli dengan nilai pengembalian dari panggilan balik Anda.

Yang perlu Anda lakukan adalah memanggil fungsi atau metode lain saat Anda memiliki baris atau tidak.

Anda menelepon:

var rows = loginM.findUser(req.body, res);

dan Anda berharap mendapatkan baris di sana, tetapi Anda tidak melakukannya. Apa yang akan Anda dapatkan adalah undefined dan Anda akan mendapatkannya lebih cepat daripada kueri basis data bahkan dimulai. Ini bekerja seperti ini:

me.findUser = function(params, res) {
    // (1) you save the username in a variable
    var username = params.username;

    // (2) you pass a function to getConnection method
    pool.getConnection(function (err, connection) {
        console.log("Connection ");

        if (err) {
            console.log("ERROR 1 ");
            res.send({"code": 100, "status": "Error in connection database"});
            return;
        }

        connection.query('select Id, Name, Password from Users ' +
            'where Users.Name = ?', [username], function (err, rows) {
            connection.release();
            if (!err) {
                return rows;
            } else {
                return false;
            }
        });

        //connection.on('error', function (err) {
        //    res.send({"code": 100, "status": "Error in connection database"});
        //    return;
        //});
    });

    // (3) you end a function and implicitly return undefined
}

pool.getConnection metode kembali segera setelah Anda melewatkan suatu fungsi, bahkan sebelum koneksi ke database dibuat. Kemudian, setelah beberapa waktu, fungsi yang Anda berikan ke metode itu mungkin dipanggil, tetapi akan lama setelah Anda mengembalikan undefined ke kode yang menginginkan nilai di:

var rows = loginM.findUser(req.body, res);

Alih-alih mengembalikan nilai dari callback, Anda perlu memanggil beberapa fungsi atau metode lain darinya (seperti beberapa callback yang perlu Anda panggil, atau metode untuk menyelesaikan janji).

Mengembalikan nilai adalah konsep sinkron dan tidak akan berfungsi untuk kode asinkron.

Bagaimana janji harus digunakan

Sekarang, jika fungsi Anda mengembalikan janji :

me.findUser = function(params, res) {
    var username = params.username;

    return new Promise(function (res, rej) {

      pool.getConnection(function (err, connection) {
        console.log("Connection ");

        if (err) {
          rej('db error');
        } else {
          connection.query('...', [username], function (err, rows) {
            connection.release();
            if (!err) {
                res(rows);
            } else {
                rej('other error');
            }
        });
      });
    });
}

maka Anda akan dapat menggunakannya di beberapa bagian lain dari kode Anda dengan cara seperti ini:

app.post('/login/', function(req, res, next) {

    var promise = new Promise(function (resolve, reject) {

        // rows is a promise now:
        var rows = loginM.findUser(req.body, res);

        rows.then(function (rowsValue) {
            console.log("Success");
            resolve(rowsValue);
        }).catch(function (err) {
            console.log("Failed");
            reject(err);
        });
    });
    // ...

Penjelasan

Singkatnya, jika Anda menjalankan operasi asinkron - seperti kueri basis data - maka Anda tidak dapat langsung memiliki nilai seperti ini:

var value = query();

karena server perlu memblokir menunggu database sebelum dapat menjalankan tugas - dan inilah yang terjadi di setiap bahasa dengan sinkron, memblokir I/O (itulah mengapa Anda perlu memiliki utas dalam bahasa tersebut sehingga hal-hal lain dapat dilakukan dilakukan saat utas itu diblokir).

Di Node, Anda dapat menggunakan fungsi panggilan balik yang diteruskan ke fungsi asinkron untuk dipanggil saat memiliki data:

query(function (error, data) {
  if (error) {
    // we have error
  } else {
    // we have data
  }
});
otherCode();

Atau Anda bisa mendapatkan janji:

var promise = query();
promise.then(function (data) {
  // we have data
}).catch(function (error) {
  // we have error
});
otherCode();

Tetapi dalam kedua kasus otherCode() akan dijalankan segera setelah mendaftarkan callback atau penangan janji Anda, sebelum kueri memiliki data apa pun - tidak ada pemblokiran yang harus dilakukan.

Ringkasan

Seluruh idenya adalah bahwa dalam lingkungan utas tunggal yang tidak sinkron, non-pemblokiran, seperti Node.JS, Anda tidak pernah melakukan lebih dari satu hal dalam satu waktu - tetapi Anda dapat menunggu banyak hal. Tapi Anda tidak hanya menunggu sesuatu dan tidak melakukan apa-apa saat menunggu, Anda menjadwalkan hal lain, menunggu lebih banyak hal, dan akhirnya Anda dipanggil kembali saat sudah siap.

Sebenarnya saya menulis cerita pendek di Medium untuk menggambarkan konsep itu:I/O Nonblacking di planet Asynchronia256/16 - Sebuah cerita pendek berdasarkan fakta yang tidak pasti .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Fungsi MySQL SIGN() – Cari Tahu Apakah Angka Positif atau Negatif di MySQL

  2. Berikan Izin ke Pengguna MySQL di Linux melalui Command Line

  3. Memeriksa beberapa kolom untuk satu nilai

  4. Kueri dengan parameter MySQL

  5. GALAT 1698 (28000):Akses ditolak untuk pengguna 'root'@'localhost'