Методы Meteor -mysql не возвращают записи - PullRequest
1 голос
/ 02 октября 2019

Я новичок в Meteor, я использую базу данных MySQL вместо MongoDB. Я хочу вернуть записи mysql из одного из методов Meteor на сервере, и я пытаюсь вернуть их, а на стороне клиента я хочу вывести их в консоль. Но это печать как «неопределенная».

enter image description here

server.js
----------

    import { Meteor } from 'meteor/meteor';
    import mysql from 'mysql';
    import { Mongo } from 'meteor/mongo';
     Meteor.methods({
        insertJobCurrent:function(EMPLID,callback) {

            var pool = mysql.createConnection({
                host: '127.0.0.1',
                user: 'root',
                password: 'abc1234',
                database: 'dbEmployees'
                //port: '31597'
            });        

            var JobCurrent=[];
            pool.query("SELECT A.EMPLID, B.NAME, A.JOBCODE, A.DEPTID, A.JOB_ENTRY_DT, A.SUPERVISOR_ID FROM Employee A JOIN names B ON A.EMPLID=B.EMPLID WHERE A.ACTIVE='Y' AND A.EMPL_RCD=0 AND A.EMPLID='"+EMPLID +"'", function (error, results, fields){

                console.log(results); // Printing the results in Meteor console
                return results;


            });

            //return jobCurrent.find().fetch();
        }
    });



client.js
--------
    Meteor.call('insertJobCurrent',employeeID, function(err, response){
            if (err) {
                console.log("error: "+ err);
                console.log(response);
            } else{

                console.log(response); // Printing undefined
                console.log("success")
            }
        }); 

Как получить результаты на стороне клиента? Спасибо, если кто-нибудь поможет мне!

1 Ответ

3 голосов
/ 03 октября 2019

Это похоже на классическое возвращаемое значение из задачи обратного вызова: Как мне вернуть ответ от асинхронного вызова?

Я не уверен, насколько вы знакомы с обратными вызовами и асинхроннымкод, но общий поток вашей функции в настоящее время:

** Method comes in
Create db connection
>> Send async query to mysql
** function ends and returns empty message to client -> client sees empty response
<< async function finishes and runs callback, result goes nowhere because response was already sent to client.

Что вы хотите сделать, это ждать , чтобы обратный вызов завершился первым.

Есть три способаВы можете сделать это с Meteor

1. Используйте Meteor.wrapAsync

    insertJobCurrent: function(EMPLID,callback) {

        var pool = mysql.createConnection({
            host: '127.0.0.1',
            user: 'root',
            password: 'abc1234',
            database: 'dbEmployees'
            //port: '31597'
        });
        // Wrap the function you want to call
        // The second parameter sets `this` in the wrapped function.
        // I have no idea if the mysql module you're using needs this, but I'm including it just in case
        const wrappedmysqlQuery = Meteor.wrapAsync(pool.query, pool);

        // Now you can call the wrapped function as though it was synchronous
        const results = wrappedmysqlQuery("SELECT A.EMPLID, B.NAME, A.JOBCODE, A.DEPTID, A.JOB_ENTRY_DT, A.SUPERVISOR_ID FROM Employee A JOIN names B ON A.EMPLID=B.EMPLID WHERE A.ACTIVE='Y' AND A.EMPL_RCD=0 AND A.EMPLID='"+EMPLID +"'")
        console.log(results); // Printing the results in Meteor console
        return results;
    }

Вот документы по Meteor.wrapAsync: https://docs.meteor.com/api/core.html#Meteor-wrapAsync

Задолго до выполнения обещаний и асинхронных функций, Meteor предоставил асинхронные вызовы в стиле синхронизации на сервере с использованием Fibers,Если вам интересно, вы можете получить краткое изложение здесь: https://benjamn.github.io/goto2015-talk/#/

2. Вернуть обещание:

    insertJobCurrent: function(EMPLID,callback) {

        var pool = mysql.createConnection({
            host: '127.0.0.1',
            user: 'root',
            password: 'abc1234',
            database: 'dbEmployees'
            //port: '31597'
        });

        return new Promise(function (resolve, reject) { 
            pool.query("SELECT A.EMPLID, B.NAME, A.JOBCODE, A.DEPTID, A.JOB_ENTRY_DT, A.SUPERVISOR_ID FROM Employee A JOIN names B ON A.EMPLID=B.EMPLID WHERE A.ACTIVE='Y' AND A.EMPL_RCD=0 AND A.EMPLID='"+EMPLID +"'", function (error, results, fields) {

                console.log(results); // Printing the results in Meteor console
                resolve(results);
            });
        }))

}

Это работает, потому что Метеор проверяет, возвращаете ли вы обещание от метода, и будет автоматически ожидать результата перед отправкой его клиенту

3. Использование Async / Await

async functions и async/await работает лучше всего, когда используемая библиотека уже возвращает обещания или если вы можете обещать функцию, о которой идет речь. Я не проверял, может ли mysql возвращать обещания, поэтому я буду использовать модуль pify для обещания функции в примере

import pify from 'pify'

    insertJobCurrent: async function(EMPLID,callback) {

        var pool = mysql.createConnection({
            host: '127.0.0.1',
            user: 'root',
            password: 'abc1234',
            database: 'dbEmployees'
            //port: '31597'
        });
        // promisify the function you want to call
        const wrappedmysqlQuery = pify(pool.query);

        // Now when we run the promisified function it returns a promise that we
        // can wait for the value of with `await`
        const results = await wrappedmysqlQuery("SELECT A.EMPLID, B.NAME, A.JOBCODE, A.DEPTID, A.JOB_ENTRY_DT, A.SUPERVISOR_ID FROM Employee A JOIN names B ON A.EMPLID=B.EMPLID WHERE A.ACTIVE='Y' AND A.EMPL_RCD=0 AND A.EMPLID='"+EMPLID +"'");

        console.log(results); // Printing the results in Meteor console
        return results;
    }

Обратите внимание, что await доступен только внутри async function. async функции всегда возвращают обещание.

Это наиболее похоже на пример Meteor, за исключением того, что в нем используется чистый JavaScript. Одно заметное отличие состоит в том, что когда Meteor видит асинхронную функцию, он действует так, как будто вы запустили this.unblock() внутри функции, и поэтому порядок вызова методов не гарантирован (в отличие от wrapAsync).

...