NodeJS Async/Await Exporting a Variable - node.js

Me again busting b***s ...
I'm sorry to have to come back to you guys, but I find the information available online very confusing and can't seem to find an appropriate answer to my problem.
So if one of you wizards/gods of the Node could help me, I'd greatly appreciate it.
I'm trying to export a variable that yields from a promise to a different module.
Here's my code:
The main:
//app.js <--- This is where I need the variable exported.
var sp1 = require('./module');
var somePromise2 = new Promise((resolve, reject) => {
resolve('Hey! It worked the second time!');
});
async function exec() {
const message1 = await sp1.msg
const message2 = await somePromise2
console.log('Success', message1, message2);
}
exec()
and the module with the promise:
//module.js
var somePromise1 = new Promise((resolve, reject) => {
var msg = '';
resolve(msg = 'Hey! It worked!');
});
module.exports = {
somePromise1,
}
As you can see the somePromise1, is actually the same as somePromise2 but in a different module. Thing is, I apparently can't seem to get the msg variable to be exported, it yields an undefined (if I do everything locally: in the same file, it works seemlessly).
Thanks in advance for your help and sorry in advance if you find this is a duplicate of an existing question...
I'crawled SO since yesterday for an answer and moved the code around but nothing seems to apply...

You have an error in importing and a mistake in using the promise:
//app.js <--- This is where I need the variable exported.
var sp1 = require('./module').somePromise1;
var somePromise2 = new Promise((resolve, reject) => {
resolve('Hey! It worked the second time!');
});
async function exec() {
const message1 = await sp1;
const message2 = await somePromise2;
console.log('Success', message1, message2);
}
exec()

Related

How do you wait for a return from a function before moving on in node

I'm new to Node so I'm struggling with this. The script runs as if its "skipping" the bitx.getTicker function inside the while loop. I did some research on asynchronous functions in Node and I just cant seem to get it working on my code. I'm trying to write a crypto-bot with bitx. I tried the .then() method as well and it just keeps on "skipping" the bitx.getTicker function. If I remove the async(from line 1), let tick = await``(from line 5) and the while``` loop it works as intended but just once. I need it to run constantly to check new asking price so once wont work. Thanks in advance.
async function get_ticker(){
let BitX = require('../lib/BitX')
while(true){
let bitx = new BitX(key, secret)
let tick = await bitx.getTicker(function (err, ticker) {
// sends ticker object to another function to get values
get_info(ticker)
})
console.log(i)
i = i + 1
}
}
UPDATE
I used a promise and I see it pending but I cant access the ticker variable inside the bitx.getTicker function. How can I access it?
function get_ticker() {
let BitX = require('../lib/BitX')
const promise = new Promise((resolve, reject) => {
let bitx = new BitX(key, secret)
bitx.getTicker(function (err, ticker) {
resolve(ticker)
})
})
return promise.resolve
}
var result = get_ticker()
console.log(result)
It seems like your BitX library doesn't have a promise interface but is callback-based, so you need to promisify it:
const { promisify } = require('util')
async function get_ticker(){
let BitX = require('../lib/BitX')
while(true){
let bitx = new BitX(key, secret)
let tick = await promisify(bitx.getTicker).call(bitx)
get_info(tick)
console.log(i)
i = i + 1
}
}
It would be more performant to create the client only once though:
const { promisify } = require('util')
const BitX = require('../lib/BitX')
const bitx = new BitX(key, secret)
const getBitxTicker = promisify(bitx.getTicker).bind(bitx)
async function get_ticker(){
while(true){
const tick = await getBitxTicker()
get_info(tick)
console.log(i)
i = i + 1
}
}
(Note that I used bind instead of call now for binding the bitx instance, because we don't immediately call it now.)

Pending promise in aws lambda function

I'm using the library JSZip to unzip a file and I am able to get each of the file name. However, what I want to do is to take the content of the file to do some processing. I know that you are able to do this by doing zip.file(name).async(type).then() according to the API.
For some reason though, when I do that in my lambda function, it doesn't hit that function at all. I tried to do return that line of code, but I just got Promise <pending>... I tried to wrap it with a try/catch and that didn't do anything. I did an async/await but that didn't work either. A callback like:
zip.file(name).async('blob').then(function(content) {
//Do processing in here
});
doesnt seem to work either. What do I need to do to get the content of the specific file? Nothing I have done is work and I think it has to do with the promise pending. I'm stuck at this point and have no idea what to do.. Any help is greatly appreciated. For reference here is my code for how I'm doing it:
let zip = new JSZip();
zip.loadAsync(file).then(function(contents) {
Object.keys(contents.files).forEach(function(name) {
zip.file(name).async('blob').then(function(content) {
// Processing here
});
});
});
EDIT
Full code:
index.js
const manager = require("./manager.js");
exports.handler = async (event, context, callback) => {
return manager.manager(event, callback);
};
manager.js
exports.manager = async function (event, callback) {
const path = '/temp/' + fileName;
const file = fs.readFileSync(path);
let zip = new JSZip();
zip.loadAsync(file).then(function(contents) {
Object.keys(contents.files).forEach(function(name) {
zip.file(name).async('blob').then(function(content) {
// Processing here
});
});
});
}
Change to have a return for the function:
return zip.loadAsync(file).then(...)

cannot make an async function using sequelize

I'm trying to get information from my model but it always returns me Promise { <pending> } or undefined (on all the ways I had tried)
Heres the code that I'm trying to use to retrieve information from DB
const cnabBody = require('../controller/cnabBody');
let resultado = cnabBody.encontrarUm().then((r) => {
console.log(r);
});
Heres my controller
const CnabBody = require ('../model/cnabBody');
exports.encontrarUm = async () => {
const { nome_campo } = await CnabBody.findOne({where:{nome_campo: "Nome do Campo"}});
return nome_campo;
}
I would need to know more about the object structure that's resolved from the findOne function, but it sounds like the nome_campo object being returned is a Promise object rather than a value. If that's the case then you'd also have to await on the nome_campo (assuming it's not undefined).
If CnabBody.findOne() returns this:
{
nome_campo: somePromise
}
then you should either change findOne to await on that Promise and send back the object it resolves to, or you need to await on it after receiving it in your controller. The latter could be done like this:
const CnabBody = require ('../model/cnabBody');
exports.encontrarUm = async () => {
const { nome_campo } = await CnabBody.findOne({where:{nome_campo: "Nome do Campo"}});
if (nome_campo) return await nome_campo; // <--- add await here if defined
}
However I'd say it's nicer if findOne could be changed (assuming you have access to the code) so that calling await CnabBody.findOne() returned the actual result and not a Promise. Having Promise that resolves another Promise seems redundant, but if you are not the author of findOne then you might not have the option to change its resolved object.
In your controller change const { nome_campo } to const nome_campo. it will work
const CnabBody = require ('../model/cnabBody');
exports.encontrarUm = async () => {
// const { nome_campo } = await CnabBody.findOne({where:{nome_campo: "Nome do Campo"}}); <== problem is here
const nome_campo = await CnabBody.findOne({where:{nome_campo: "Nome do Campo"}});
return nome_campo;
}
I was calling my async functions inside a function that wasnt async soo when i tried any await method it wasnt awaiting or returning a error soo i changed my first line
wb.xlsx.readFile(filePath).then(function(){
to
wb.xlsx.readFile(filePath).then(async function(){
soo my code looks like this now and it is working fine. (:
wb.xlsx.readFile(filePath).then(async function(){
var sh = wb.getWorksheet("Sheet1");
// console.log(sh.getCell("A1").value);
const field = await cnabContent.findOne({where: {nome_campo: "Nome do Campos"}});
console.log(field);
});
Thanks for all that tried to help me, made me do alot of searchs and read about promises, async and await and get this solution.

Node.js Await Async with util class function

I am fairly new to Node.js and I am trying to pick it up with Koa.js framework.
I am struggling to understand why the index.js -> console.log run even if I have the await in the value.
Can anyone point me in the right direction?
index.js
router.get('getValue','/display',async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData()
console.log(result)
}
util.js
async function getData(){
var customObject =[]
var standardObject =[]
conn.describeGlobal(function (err,res){
if (err){return console.error(err)}
console.log('No of Objects ' + res.sobjects.length)
res.sobjects.forEach(function(sobject){
if (sobject.custom){
customObject.push(sobject)
}else{
standardObject.push(sobject)
}
})
console.log("Done")
})
return [customObject, standardObject]
}
Try this one
await, works inside async functions
router.get('getValue','/display', async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData();
console.log(result)
});
function getData(){
return new Promise((resolve, reject) => {
resolve('result goes here');
});
}
You need to specify the function is async for the await to work.
Something like this:
router.get('getValue','/display', async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData()
console.log(result)
}
Hope this helps :)
In your function getData(), I think you've missplaced your return statement. The return statement should be placed inside the callback function used for conn.describeGlobal().
As you actually write your getData(), the conn.describeGlobal() call seems to be an asynchronous treatment, so the return statement placed outside is probably executed before you pushed something in your arrays.
The consequence is that your router get an empty response from your getData() function then the promise made by await keyword is resolved with an empty answer.

Async Await Promise <Pending>

I know this question been asked for many times but as I'm still very new i dont quite understand the answers on previous places.
const publicIp = require('public-ip');
// getting ip address
async function GetIpAddress() {
var a = await publicIp.v4();
return await a;
// it will return my public ip as string
}
however ,as its non blocking i understand if i do something like this as below
var a = GetIpAddress();
console.log(a);
it will probably go promise pending. so what i did was
async function hi(){
var a = await GetIpAddress();
console.log(a);
}
hi();
But here's my question. How do i return it back to my variables without making another function to cover it up? please see code below
var zmq = require('zmq'),
requester = zmq.socket('req'),
publicIp = require('public-ip');
const PORT = "3222";
var IP = GetIpAddress();
console.log(`${IP}:${PORT}`);
// IP will return promise pending?? how i do fix this without making another
// function?
requester.connect('tcp://127.0.0.1:5433');
requester.on('message', function (msg) {
// arr = str.split(",");
console.log(msg.toString());
});
requester.send(
`${IP}:${PORT}`
);
async function GetIpAddress() {
var a = await publicIp.v4();
return a
}
As the full code above shown.. var IP will definitely be promise pending as it will take time. therefore how do it get the function return value without making another function?
EDIT: please understand the duplication is entirely not what i want.. I understand that my knowlege on callbacks , promises and async await wasnt strong but from a guy who comes from synchronous language such as Python itself . I'm very curious onto how do i take variable out. as what i research and saw are mostly
promises within promises or callbacks within callbacks.
what i want is if i can rereplicate what was shown as per below ( python )
def f(x):
return x+1
var1 = 5
var1 = f(var1)
# var1 is now 6
which is bringing callbacks / promises / async await variable out of its own function rather than
var IP = GetIpAddress().then((IP) => {
requester.connect('tcp://127.0.0.1:5433');
console.log('Worker connected to port 5433');
requester.on('message', function (msg) {
// arr = str.split(",");
console.log(msg.toString());
});
requester.send(
`${IP}:${PORT}`
);
console.log(`${IP}:${PORT}`);
});
Change:
var IP = GetIpAddress();
console.log(`${IP}:${PORT}`);
to:
GetIpAddress().then((IP) => {
console.log(`${IP}:${PORT}`);
}
);
You can read 6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)
Update:
Option 1 put everything in the then:
GetIpAddress().then((IP) => {
requester.connect('tcp://127.0.0.1:5433');
console.log('Worker connected to port 5433');
requester.on('message', function (msg) {
// arr = str.split(",");
console.log(msg.toString());
});
requester.send(
`${IP}:${PORT}`
);
console.log(`${IP}:${PORT}`);
});
Option 2 is to wrap everything in an async function:
async function hi(){
var a = await GetIpAddress();
console.log(a);
}
hi();
Option 2 is the one I would opt for as it provides a cleaner way of writing things.
you need to add await before the method call. the main method also need to async.
var IP = await GetIpAddress();
try to use
new promise(function (accept, reject){ // if Ip found
accept("ipaddress") //else reject("error log")
}).then(function(response){ // this is accept , print IPaddress
}).catch(function(err){ // this is reject. } );

Resources