Async Await Node js - node.js

I am learning async await using node js
var testasync = async () =>
{
const result1 = await returnone();
return result1;
}
testasync().then((name)=>{
console.log(name);
}).catch((e) =>{
console.log(e);
});
var returnone = () =>{
return new Promise((resolve,reject)=>
{
setTimeout(()=>{
resolve('1');
},2000)
})
}
It fails with returnone is not a function. What am i doing wrong? calling the function just by itself work
returnone().then((name1) => {
console.log(name1)
})
Just calling the above code works

The reason you are getting this error because of hoisting. Your code seen by JS would look like this
var returnone;
var testasync = async () => {
const result1 = await returnone();
return result1;
}
testasync().then((name) => {
console.log(name);
}).catch((e) => {
console.log(e);
});
returnone = () => {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('1');
}, 2000)
})
}
So the value of returnone is undefined.

You are assigning the function to the variable returnone at the end of the code, but you are trying to call that function before this assignment. You have two options to fix the code:
Option 1
Use a function declaration; this way, the function is hoisted and you can use it right from the start:
var testasync = async () => {
const result1 = await returnone();
return result1;
}
testasync().then((name) => {
console.log(name);
}).catch((e) => {
console.log(e);
});
function returnone() {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('1');
}, 2000)
})
}
Option 2
Assign the function to the variable before you try to call it:
var returnone = () => {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('1');
}, 2000)
})
}
var testasync = async () => {
const result1 = await returnone();
return result1;
}
testasync().then((name) => {
console.log(name);
}).catch((e) => {
console.log(e);
});

Related

jest test async function which neither return promise nor accept callback

//index.js
export let usersList = [];
export function getUser() {
fetch("https://jsonplaceholder.typicode.com/users")
.then((x) => x.json())
.then((users) => {
setTimeout(() => {
usersList = users;
}, 2000); //fake delay
});
}
getUser();
//index.test.js
const { getUser, usersList } = require("./index");
it("should fetch users and assign to usersList", () => {
getUser();
expect(usersList.length).toBe(10); //Error: Expected: 10, Received: 0
});

function, that returns Promise

I have a task with a promise and I don't understand how to do it.please help
1.Imports function "func1" from file "script1.js";
const func1 = a => {
switch (a) {
case 'a':
return new Promise((resolve) => {
setTimeout(() => {
resolve('result1');
}, 100);
});
case 'b':
return new Promise((resolve) => {
setTimeout(() => {
resolve('result2');
}, 100);
});
default:
return new Promise((resolve) => {
setTimeout(() => {
resolve('result3');
}, 100);
});
};
};
module.exports = func1;
Reads a string from the "input.txt";
input a
Calls "func1" with an argument equal to the string;
Waits until the received Promise has state: "fulfilled" and then outputs the result to the file "output.txt".
this is how i try to solve but nothing works:
const fs = require('fs')
const func1 =require ("./script1 (1)")
fs.readFile('./input.txt', 'utf8' , (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data)
async function one (data) {
try {
const result = await Promise(func1);
console.log(result);
} catch (err) {
console.log(err)
}}
fs.writeFile("output.txt",one().toString(), function(err)
{
if (err)
{
return console.error(err);
}
})
})
the result must be "result1"
To call a Promise you can use async await and try catch blocks. Once you have the asynchronous result value, you can call fs.writeFile(). Try this:
func1.js:
const func1 = a => {
switch (a) {
case 'a': return new Promise((resolve) => {
setTimeout(() => { resolve('result1'); }, 100);
});
case 'b': return new Promise((resolve) => {
setTimeout(() => { resolve('result2'); }, 100);
});
default: return new Promise((resolve) => {
setTimeout(() => { resolve('result3'); }, 100);
});
};
};
module.exports = func1;
index.js:
const fs = require('fs');
const func1 = require("./demo2.js")
fs.readFile('./input.txt', 'utf8' , async (err, data) => {
if (err) {
console.error(err);
return;
}
//console.log(data)
try {
const result = await func1(data);
console.log(result);
fs.writeFile("output.txt", result, function(err) {
if (err){
return console.error(err);
}
});
} catch (err) {
console.log(err)
}
});
the async/await way is to change const result = await Promise(func1); to const result = await func1(data); you can also use then like this const result = func1(data).then(res => res);
and a better func1 would be
const func1 = a => {
return new Promise((resolve) => {
setTimeout(() => {
switch(a) { // handle cases };
});
});
};
module.exports = func1;
const func1 = a => {
return new Promise((resolve) => {
switch (a) {
case 'a':
setTimeout(() => {
resolve('result1');
}, 100);
case 'b':
setTimeout(() => {
resolve('result2');
}, 100);
default:
setTimeout(() => {
resolve('result3');
}, 100);
};
})
};
module.exports = func1;
const fs = require('fs')
const func1 =require ("./script1 (1)")
fs.readFile("./input.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
async function one(data) {
try {
func1(data).then(result => {
console.log(result)
})
} catch (err) {
console.log(err);
}
}
fs.writeFile("output.txt", one().toString(), function (err) {
if (err) {
return console.error(err);
}
});
});

In node.js, why is my data not getting passed back after a asynchronous file read using a Promise

I know for sure that my pullData module is getting the data back from the file read but the function calling it, though it has an await, is not getting the data.
This is the module (./initialise.js) that reads the data:
const fs = require('fs');
const getData = () => {
return new Promise((resolve, reject) => {
fs.readFile('./Sybernika.txt',
{ encoding: 'utf8', flag: 'r' },
function (err, data) {
if (err)
reject(err);
else
resolve(data);
});
});
};
module.exports = {getData};
And this is where it gets called (app.js):
const init = require('./initialise');
const pullData = async () => {
init.getData().then((data) => {
return data;
}).catch((err) => {
console.log(err);
});
};
const start = async() => {
let data = await pullData();
console.log(data);
}
start();
putting 'console.log(data)' just before return(data) in the resolve part of the call shows the data so I know it's being read OK. However, that final console.log shows my data variabkle as being undefined.
Any suggestions?
It's either
const pullData = async () => {
return init.getData().then((data) => {
return data;
}).catch((err) => {
console.log(err);
});
};
or
const pullData = async () =>
init.getData().then((data) => {
return data;
}).catch((err) => {
console.log(err);
});
Both versions make sure a promise returned by then/catch is passed down to the caller.

Jest - how to mock a Class used by a module?

I have a class :
class RequestTimeout {
constructor(timeoutMilliseconds) {
this.timeoutMilliseconds = timeoutMilliseconds;
this.timeoutID = undefined;
}
start() {
return new Promise((resolve, reject) => {
this.timeoutID = setTimeout(() => reject(new Error(`Request attempt exceeded timeout of ${this.timeoutMilliseconds}`)), this.timeoutMilliseconds);
});
}
clear() {
if (this.timeoutID) clearTimeout(this.timeoutID);
}
}
module.exports = RequestTimeout;
This class is used in a module:
const RequestTimeout = require('./request-timeout');
function Request() {
...
async function withTimeout(request, ms) {
const timeout = new RequestTimeout(ms);
return Promise.race([
request(),
timeout.start(),
])
.then(
response => {
timeout.clear();
return response;
},
err => {
timeout.clear();
throw err;
}
);
}
...
}
How do i mock RequestTimeout in a test using Request? For example:
it('should clear the timeout following a successful response', async () => {
nock('http://example.com')
.get('/')
.reply(200, { example: true });
const response = await request.get({ ...baseOptions });
expect(response.example).toEqual(true);
});
// MOCK
let mockGetTimeOutId = jest.fn();
jest.mock('../request-timeout', () => {
return jest.fn().mockImplementation((ms) => {
let timeoutId = undefined;
return {
start: () => new Promise((resolve, reject) => {
timeoutId = setTimeout(() => reject(), ms);
}),
clear: () => mockGetTimeOutId(timeoutId),
}
})
});
// TEST
it('should clear the timeout following a successful response', async () => {
nock('http://example.com')
.get('/')
.reply(200, { example: true });
expect(mockGetTimeOutId).toHaveBeenCalledTimes(0);
const response = await request.get({ ...baseOptions });
expect(mockGetTimeOutId).toHaveBeenCalledTimes(1);
expect(response.example).toEqual(true);
});

How can i access nested promise data?

I am trying to set up a route that sends data from a nested promise to my vue app.
But i'm having trouble with the getting data from the nested promises.
i tried using a callback with no success
app.get('/notification', (req, res) => {
const getData = (data) => {
console.log(data)
}
scheduler(data)
})
const scheduler = (callback) => {
sftp
.connect({ credentials })
.then(() => {
return sftp.list(root);
})
.then(async data =>
{
const filteredFile = data.filter(file => {
let currentDate = moment();
let CurrentTimeMinusFive = moment().subtract(5, "minutes");
let allAccessTimes = file.accessTime;
let parsedAccessTimes = moment(allAccessTimes);
let filteredTime = moment(parsedAccessTimes).isBetween(
CurrentTimeMinusFive,
currentDate
);
return filteredTime;
});
for (const file of filteredFile) {
let name = file.name;
let filteredThing;
await sftp
.get(`Inbound/${name}`)
.then(data => {
csv()
.fromString(data.toString())
.subscribe(function (jsonObj) {
return new Promise(function (resolve, reject) {
filteredThing = new Notification(jsonObj);
filteredThing.save()
.then(result => {
console.log(result);
callback(result) **// THIS IS THE RESULT I NEED IN MY FRONT END**
})
.catch(err => {
console.log(err);
});
resolve();
});
});
});
}
})
When i go to localhost/notification i get:
ReferenceError: data is not defined
Thanks in advance!

Resources