NodeJs/Electron : How to wait for function to finish before ipcMain send back his answer?

Viewed 9496

I am learning nodejs and electron and I am trying to receive data from my renderer, treats those data, and send them back to it. But my treat function is too slow or I don't really know and so the ipc send back the data too early and make undefined data. In short, I want my treat function to finish before the ipcMain event send back a message. Here's just an example of where I am stuck, it's not my real code though, I can send you the real but it's really messy, like a lot..

// In main process.
const {ipcMain} = require('electron')

function treatData (input) {
var treated = treat(input)
    // ...
console.log(treated) // prints the actual treated data
return treated;
}

ipcMain.on('asynchronous-message', (event, rawdata) => {
  console.log(rawdata) // prints my raw data
  var dataTreated = treatData(rawdata)
  console.log(dataTreated) // prints Undefined
  event.sender.send('asynchronous-reply', dataTreated) // send Undefined data
})

As i'm learning new things everyday, I am often stuck to basic stuff I think... But here am I and I need your help. I've already looked for problem like mine but I can't find anything because I don't know what the problem is actually called. I searched around for asynchronous function with async and await but I don't know how possible I can put them here. Because async seems to doesn't work with ipcMain or I don't know what am I missing but that doesn't work :

async function RenderMessage () {
ipcMain.on('asynchronous-message', (event, rawdata) => {
  console.log(rawdata) // prints my raw data
  var dataTreated = await treatData(rawdata)
  console.log(dataTreated) // prints Undefined
  event.sender.send('asynchronous-reply', dataTreated) // send Undefined data
 })
}

It returns "await is a reserved word"

Thanks in advance !

3 Answers

You missing two important things to achieve a callback waiting up an other function:

  1. Your function (to be waited) should return a Promise object for being able to be awaited
  2. Your callback should be an async function for being able to await
const {ipcMain} = require('electron')

function treatData (input) {
  return new Promise((resolve, reject) => {
    var treated = treat(input)
    // ...
    resolve(treated)
  })
}
ipcMain.on('asynchronous-message', async (event, rawdata) => {
  var dataTreated = await treatData(rawdata)
  event.sender.send('asynchronous-reply', dataTreated)
})

Your code may be missing the async keyword. So it should be

function sendMessage () {
  ipcMain.on('asynchronous-message', async (event, rawdata) => {
    console.log(rawdata) // prints my raw data
    var dataTreated = await treatData(rawdata)
    console.log(dataTreated) // prints Undefined
    event.sender.send('asynchronous-reply', dataTreated) // send Undefined data
   })
}

It seems like your treatData() function has asynchronous behavior. Make following changes:

// In main process.
const {ipcMain} = require('electron')

async function treatData (input) {
  try{
    var treated = treat(input)
    // ...
    console.log(treated) // prints the actual treated data
    return treated;
  }
  catch(err){
    // handle error
  }

}

ipcMain.on('asynchronous-message', async (event, rawdata) => {
  console.log(rawdata) // prints my raw data
  var dataTreated = await treatData(rawdata)
  console.log(dataTreated) // will print the actual data
  event.sender.send('asynchronous-reply', dataTreated)
})

And if your treat() function contains some asynchronous code then make it async and use,

var treated = await treat(input)
Related