Javascript函数在执行前返回值

标签 javascript node.js asynchronous cassandra async-await

我正在使用 Node.JsCassandra 编写聊天应用程序。在后端调用函数 saveDataToCassandra 后,它会在将数据保存到 Cassandra 之前返回。是 Cassandra 问题还是 Javascript 问题?我的 app.js 代码片段是:

const cassandra = require('./routes/cassandra');
....
let result = cassandra.saveDataToCassandra(reqData);
console.log(`result: ${JSON.stringify(result)}`);

我的 cassandra.js 代码段是:

var saveDataToCassandra = (req) => {
    const roomId = req.roomId;
    const roomName = req.roomName;
    let participants = [];
    participants = req.participant;
    console.log("participant's list",participants);
    const formatted_date  = req.roomCreationTimestamp;

    var query = `insert into chat_app.chat_rooms(room_id,room_name,participant_type,participant,role,room_creation_date) values (?,?,?,?,?,?);`;
    participants.forEach((participant) => {
        var params = [roomId, roomName, participant.type, participant.username,participant.role, formatted_date];
        console.log(`params: ${params}`);
        client.execute(query,params,{prepare: true},(error, result) => {
            if(error){
                console.log(`error in inserting: ${error}`);
                genericResponse['status'] = "error";
                genericResponse['message'] = error;
                genericResponse['responseObject'] = {
                    roomId: roomId,
                    userName: participant.username
                };
                console.log(`generic response error: ${JSON.stringify(genericResponse)}`);
            }
            else {
                console.log(`insert result: ${JSON.stringify(result)}`);
                genericResponse['status'] = "success";
                genericResponse['message'] = "Successfully Inserted!";
                genericResponse['responseObject'] = {
                    roomId: roomId,
                    roomName: roomName,
                    participant: participant.username
                }
                console.log(`generic response success: ${JSON.stringify(genericResponse)}`);    
            }
        });
    });
    console.log(`generic response before returning: ${JSON.stringify(genericResponse)}`);
    return genericResponse;
}

问题:

participant's list [ { username: 'alice',
    role: 'teacher',
    type: 'Owner' },
  { username: 'bob',
    role: 'student',
    type: 'participant' } ]
params:
    791c6abfaa962ca60abb776d04d89a32937024f5, alice&bob, Owner,alice,teacher,2019-12-12 17:33:54
params: 
    791c6abfaa962ca60abb776d04d89a32937024f5, alice&bob,participant,bob,student,2019-12-12 17:33:54
generic response before returning: {"status":"","message":"","responseObject":""}
result: {"status":"","message":"","responseObject":""}
insert result: {"info":{"queriedHost":"127.0.0.1:9042","triedHosts":{"127.0.0.1:9042":null},"speculativeExecutions":0,"achievedConsistency":10,"isSchemaInAgreement":true},"columns":null,"pageState":null}
generic response success: {"status":"success","message":"Successfully Inserted!","responseObject":{"roomId":"791c6abfaa962ca60abb776d04d89a32937024f5","roomName":"alice&bob","participant":"alice"}}
insert result: {"info":{"queriedHost":"127.0.0.1:9042","triedHosts":{"127.0.0.1:9042":null},"speculativeExecutions":0,"achievedConsistency":10,"isSchemaInAgreement":true},"columns":null,"pageState":null}
generic response success: {"status":"success","message":"Successfully Inserted!","responseObject":{"roomId":"791c6abfaa962ca60abb776d04d89a32937024f5","roomName":"alice&bob","participant":"bob"}}

现在的问题是 saveDataToCassandra 首先返回 genericResponse,然后数据存储在 Cassandra 上。我想在将数据保存到 Cassandra 后返回响应。请帮我解决这个问题。预先感谢:)

最佳答案

我猜你构建代码的方式不是编写的。您正在 foreach 循环中调用回调样式函数,并且当您调用方法时,您不会等待。如果像这样提取执行方法

function execute(participant, query) {
  return new Promise((resolve, reject) => {
    client.execute(query,params,{prepare: true}, (error, result) => {
    if(error){
        console.log(`error in inserting: ${error}`);
        genericResponse['status'] = "error";
        genericResponse['message'] = error;
        genericResponse['responseObject'] = {
            roomId: roomId,
            userName: participant.username
        };
        console.log(`generic response error: ${JSON.stringify(genericResponse)}`);
        reject(genericResponse);
    }
    else {
        console.log(`insert result: ${JSON.stringify(result)}`);
        genericResponse['status'] = "success";
        genericResponse['message'] = "Successfully Inserted!";
        genericResponse['responseObject'] = {
            roomId: roomId,
            roomName: roomName,
            participant: participant.username
        }
        console.log(`generic response success: ${JSON.stringify(genericResponse)}`); 
        resolve(genericResponse);   
    }
  });
});

像这样改变你的保存方法 - 基本上使用promise all而不是foreach

var saveDataToCassandra = (req) => {
  const roomId = req.roomId;
  const roomName = req.roomName;
  let participants = [];
  participants = req.participant;
  console.log("participant's list",participants);
  const formatted_date  = req.roomCreationTimestamp;

  var query = `insert into chat_app.chat_rooms(room_id,room_name,participant_type,participant,role,room_creation_date) values (?,?,?,?,?,?);`;
  return Promise.all(participants.map(participant => {
      var params = [roomId, roomName, participant.type, participant.username,participant.role, formatted_date];
      console.log(`params: ${params}`);
      return execute(participant, query);
  }));
};

当你需要结果时使用 then

const cassandra = require('./routes/cassandra');

cassandra.saveDataToCassandra(reqData)
  .then(result => console.log(result));

您还可以使用 async/await,但此示例使用的是 Promise。希望这会有所帮助。

关于Javascript函数在执行前返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59305082/

相关文章:

php - 如何构建多站点管理器应用程序?

c++ - nodejs 插件错误 : Unable to load shared library

javascript - Node.js 在逐行 Readline 完成后执行

带有自定义参数的 Javascript 回调

javascript - 用于滑动事件的按钮,无需单击默认动画

javascript - NodeJS 脚本中的变量自动重置为其初始值?

javascript - 同时使用 Knockout.js 和 Polymer 会导致错误

javascript - 简单的 JavaScript 计算器

javascript - 使用变量浏览 yaml 文件

node.js - 作为事件驱动的服务器,为什么 node.js 需要异步代码而 Nginx 不需要?