Home > Net >  Node.js Returning a value from an async function - Electron
Node.js Returning a value from an async function - Electron

Time:06-21

I am creating a project where I need to take a user input - pass it through a function and return the new value to the user - seems simple enough. I am new to async functions and have read everything I possibly can, and can't works out if there's a more fundamental issue I am missing. I will show the basic code, and then what I wish to achieve. I believe the issue, is that I am returning back the status of the function rather than the value, but just can't work it out.

Basic Code:

ipcMain.on('gpt3', (event, args) => {
    async function gpt3(args) {
        generateResponse('james', 'hello world'); // Takes a user's name & input and recieves a response from a python file.
        event.reply('textRecieve', 'hello world'); // Sends 'Hello World' to the user (ipcRenderer 'textRecieve')
    }
    
    gpt3(args);

})

async function generateResponse(name, text) {
    let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
    let content = "";
    try {
      testshell.on('message', function (message) {
        console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
        return message; // attempting to return the 'Message' from the python file
      });
    } catch (error) {
      console.log("You've f*cked it somewhere my friend");
      console.log(error);
    } 
}

Python Script:

import sys

name = sys.argv[1]
text = sys.argv[2]

print(f'Python File: {name} Text: {text}')
sys.stdout.flush()

Returns: (as expected)

> Executing task: npm run start <


> [email protected] start
> electron .

Python File: james Text: hello world

What I'd Like it to do:

ipcMain.on('gpt3', (event, args) => {
    async function gpt3(args) {
        message = generateResponse('james', 'hello world'); // Takes a user's name & input and recieves a response from a python file, retunring the message to the 'message' variable.
        console.log(message);
        event.reply('textRecieve', 'message would send here'); // Sends the 'Message' to the user (ipcRenderer 'textRecieve')
    }

    gpt3(args);

  })


async function generateResponse(name, text) {
  let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
  let content = ""
  try {
    testshell.on('message', function (message) {
      console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
      return message; // attempting to return the 'Message' from the python file
    });
  } catch (error) {
    console.log("You've f*cked it somewhere my friend")
    console.log(error)
  } 
  return content; // content needs to be message instead due to async nature it returns empty string
}

Returns:

> Executing task: npm run start <


> [email protected] start
> electron .

Promise { '' }
Python File: james Text: hello world

TLDR; I would like to take the 'message' generated through 'generateResponse()' and pass it through to my 'event.reply()'. Instead, I am receiving what I believe to be the status of the Promise. Any help would be greatly appreciated. Thanks

CodePudding user response:

You should resolve the promise first.

ipcMain.on('gpt3', (event, args) => {
    async function gpt3(args) {
        const message = await generateResponse('james', 'hello world'); 
        console.log(message);
        event.reply('textRecieve', 'message would send here'); // Sends the 'Message' to the user (ipcRenderer 'textRecieve')
    }

    gpt3(args);

  })


async function generateResponse(name, text) {
  let testshell = new PythonShell('./python/text_echo.py', { mode: 'text', args: [name, text]});
  let content = ""
  try {
    testshell.on('message', function (message) {
      console.log(message); // prints the output from the python file 'Python File: james Text: hello world'
      content = message;
    });
  } catch (error) {
    console.log("You've f*cked it somewhere my friend")
    console.log(error)
  } 
  return content; // content needs to be message instead due to async nature it returns empty string
}

CodePudding user response:

Okay, so there were a few problems here... but the main was node.js 'non-ability' to pass variables around when 'asynchronous'. with node.js being new to me, I can't lie and say I was confused. Hopefully, the following link to a great workaround/method and my working code will be able to help someone:

screenshot of example code from other SO user https://stackoverflow.com/a/23667087/10246221

for some reason, it hadn't clicked with me that functions could be nested within functions like this, all in one line. For someone who is used to JS or node.js this may seem fundamental, but seeing as this is a first-time project to me, and maybe others - if still using python code. Hopefully, this may help!

ipcMain.on('gpt3', (event, input) => { gpt3Async(event, input, function(result) { event.reply('textRecieve', result); console.log('gpt3Async: '  result);})})
  • Related