Node.js 节点在插入之前关闭DB连接,或者根本不关闭

Node.js 节点在插入之前关闭DB连接,或者根本不关闭,node.js,asynchronous,Node.js,Asynchronous,我有以下代码,可以执行以下操作: 打开数据库连接(使用) 调用Twitter趋势API(针对不同的地方调用一次或多次) 检查趋势项并将每个项存储到数据库中 关闭数据库连接 我试了一个直截了当的密码。我首先面临以下错误 错误:连接被用户终止 这是代码 client.connect(); const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4,

我有以下代码,可以执行以下操作:

  • 打开数据库连接(使用)
  • 调用Twitter趋势API(针对不同的地方调用一次或多次)
  • 检查趋势项并将每个项存储到数据库中
  • 关闭数据库连接
我试了一个直截了当的密码。我首先面临以下错误

错误:连接被用户终止

这是代码

client.connect();

const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4, $5) RETURNING *';

T.get('trends/place', { id: 2295424 }, function(err, data, response) {
    data_json = data[0];
    var rankNum = 0;
    console.log(data_json.locations[0].name);
    for (var item of data_json.trends) {
        rankNum++;
        var values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
        client.query(text, values)
            .then(res => {
                console.log(res.rows[0])
            })
            .catch(e => console.error(e.stack));
    };
    client.end();
});
看起来,数据库连接(
client.end()
)在运行
client.query()
之前被调用并关闭。因此,我重写了代码,等待client.query完成,然后使用async/await调用client.end

client.connect();

const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4, $5) RETURNING *';

T.get('trends/place', { id: 23424848 }, function (err, data, response) {
    data_json = data[0];
    var rankNum = 0;
    console.log(data_json.locations[0].name);

    function insRows(){
    return new Promise( resolve => {
        for (var item of data_json.trends) {
        rankNum++;
        var values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
        client.query(text, values)
            .then(res => {
                console.log(res.rows[0])
            })
            .catch(e => console.error(e.stack));
        };
    });
    };

    async function closeDBConnection(){
        const a = await insRows();
        client.end();
        return 0;
    };

    closeDBConnection().then( v => {
         console.log(v);
    });
});
这段带有async/await的代码运行良好,但是数据库连接没有关闭,节点只是挂起,等待我按CTRL+C键

  • 节点版本:v9.2.1
  • 我使用命令运行程序:
    node app.js
更新1 使用Promise数组和async/await更新了代码。这不起作用:

client.connect();

const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4, $5) RETURNING *';
T.get('trends/place', { id: 23424848 }, function(err, data, response) {
    const data_json = data[0];
    let rankNum = 0;
    const queryPromises = [];
    console.log(data_json.locations[0].name);
    async function insRows() {
        for (let item of data_json.trends) {
            rankNum++;
            const values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
            queryPromises.push(client.query(text, values)
                .then(res => console.log(res.rows[0]))
                .catch(e => console.error(e.stack)));
        };
    };

    (async = () => {
        await Promise.all(queryPromises);
        client.end();
    });
});
我还尝试:

    async function insRows(){
     /* same as above*/
    }
    await Promise.all(queryPromises);
    client.end();
我得到以下错误(
node app_ans.js
):


您的代码从不调用您创建的承诺的
resolve
,但您不需要创建自己的承诺,因为
client.query
已返回承诺。我会这样写:

const data_json = data[0];
let rankNum = 0;
const queryPromises = [];

for (let item of data_json.trends) {
    rankNum++;
    const values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
    queryPromises.push(client.query(text, values)
        .then(res => console.log(res.rows[0]))
        .catch(e => console.error(e.stack)));
};
await Promise.all(queryPromises);
client.end();

首先,我假设您正在使用npm request包将GET请求放到twitter上,如果是,我建议使用request promise;它允许我们直接使用Async/Wait,因为它支持承诺而不是回调。话虽如此,问题可能在于您构建GET请求的方式。使用
T.get('trends/place?id=23424848'
代替
T.get('trends/place',{id:23424848}

你也可以考虑下面的代码:

const T = require('request-promise')
const { Client } = require('pg')
const client = new Client()

await client.connect()

const getTrendsAndUpdate = async (id) => {
    const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4, $5) RETURNING *';

    const closeDBConnection = async () => {
        await client.end();
        console.log('DB Connection closed')
        return 0;
    }

    try{
        const data_json = await T.get('trends/place?id='+id, {json:true});
        let trends = data_json['trends'];
        let as_of = data_json['as_of'];
        let location_name = data_json['locations']['name'];
        let rankNum = 0;
        let a = await trends.forEach(async item => {
            rankNum++;
            let values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
            let res = await client.query(text, values)
            console.log(res.rows[0])
        });
        if(a){
            await closeDBConnection()
            return
        }
    } catch(e){ console.error(e.stack) }
}

getTrendsAndUpdate(23424848)

希望这能解决问题并为您指明正确的方向。

感谢您的快速响应。我将稍后尝试一下。奇怪的是,我被这个错误击中了。我在节点v9.2.1上
/apps/twttrend/app_ans.js:37等待承诺。全部(queryPromises)^^^^^^^^语法错误:wait仅在异步函数中有效
@Guru您需要将
insRows
设置为异步函数。仍然有一些错误。我收到了相同的错误。我用整个代码更新了问题。您可以删除
async=
部分。您需要回调
T.get
async.
T.get('trends/place',{id:2295424},异步函数(…
insRows
不需要是它自己的函数。谢谢你,Nagaraja。我使用“twit”npm包连接到Twitter API。我参考了node-postgres.com的例子,但有点不足。我现在已经让它工作了。
const T = require('request-promise')
const { Client } = require('pg')
const client = new Client()

await client.connect()

const getTrendsAndUpdate = async (id) => {
    const text = 'INSERT INTO TRENDS(AS_OF, location_name, name, tweet_volume, rank) VALUES($1, $2, $3, $4, $5) RETURNING *';

    const closeDBConnection = async () => {
        await client.end();
        console.log('DB Connection closed')
        return 0;
    }

    try{
        const data_json = await T.get('trends/place?id='+id, {json:true});
        let trends = data_json['trends'];
        let as_of = data_json['as_of'];
        let location_name = data_json['locations']['name'];
        let rankNum = 0;
        let a = await trends.forEach(async item => {
            rankNum++;
            let values = [data_json.as_of, data_json.locations[0].name, item.name, item.tweet_volume, rankNum];
            let res = await client.query(text, values)
            console.log(res.rows[0])
        });
        if(a){
            await closeDBConnection()
            return
        }
    } catch(e){ console.error(e.stack) }
}

getTrendsAndUpdate(23424848)