Unable to resolving the promise inside of a function - javascript

Here is a piece of my original code, Why I can't resolve the instruct function this way?
Actually I used to resolve the promises like this and the same codes for other functions worked before.
I'm not able to find the reason and the solution without a hand.
var instructResolve;
async function instruct(location, category){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
instructResolve();
break;
}
return new Promise((resolve) => {
instructResolve = resolve;
});
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
recognize();
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
At the recognize function I'm waiting for the instruct function to resolve and then we do stuff like logging some success message on the console, but since recognize for some reason doesn't resolve we can not see the console.log('Final log success!')
UPDATE:
I have a similar code that works just fine without any issues, I have implemented the promises and resolves just like the code above but it works!
var updateGuiderResolve;
function updateGuider(state, guide, lower){
console.log('updateGuider...')
switch(state) {
case 'default':
stateReveal("default");
break;
}
return new Promise((resolve) => {
updateGuiderResolve = resolve;
});
}
function stateReveal(state){
console.log('stateReveal...')
setTimeout(function(){
speak();
}, 5000);
}
function speak(){
console.log('speak...')
setTimeout(function(){
console.log('updateGuiderResolve...')
updateGuiderResolve()
}, 5000);
}
async function tutor(){
await updateGuider('default');
console.log('final...')
}
tutor()

I can see 2 problems in the code base.
One is
instructResolve(); // It's not function, I think as it's only declared at first.
Second one is
await instruct('User_Was_Silent'); // This does not need to add await as it's already async function. Simply call instruct('User_Was_Silent'); and missing second param in this function.
var instructResolve;
async function instruct(location, category=null){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
break;
}
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
recognize();

Try calling instructResolve inside Promise like that:
var instructResolve;
async function instruct(location, category){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
break;
}
return new Promise((resolve) => {
instructResolve = resolve;
instructResolve();
});
}

There is a solution like this one but I want to know why the question's code doesn't work?
var instructResolve;
async function instruct(location, category){
return new Promise(async (resolve) => {
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
resolve();
break;
}
});
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
recognize();

Related

resolve and reject issue using node js

Is this possible way to return resolve or reject message from one function to another?
As I am writing to pass resolve message in postman whenever my task is completed or reject message when there is some error
But after after writing return it still not returning the resolve message or reject message inside Postman
any idea how this can be resolve?
async function readFile(filePath) {}
async function getAllFile(filePath) {
const paths = await readFile(filePath);
}
async function filterFiles(filePath) {
const paths = await getAllFile(filePath);
}
function addDocument(childProduct){
return new Promise((resolve, reject) => {
Document.create({
name: childProduct,
},
}).then(function (filePath) {
filterFiles(filePath);
let msg = "Document created Succesfully";
return resolve(msg);
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
});
}
function updateDoc(data){
return new Promise((resolve, reject) => {
Document.update({
name: data.name,
}
where: {
product_id: data,
},
})
}).then(function (childProduct) {
addDocument(childProduct);
let msg = "Updated Successfully";
return resolve(msg);
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
}
Product.findOne and Document.findAll return a Promise, so they can be returned and awaited directly.
You can chain await func1(); await func2(); await func3() in one try{} block, and catch any error that happens in one place :
const filterFiles = async filePath => {
const paths = await getAllFiles(filePath);
// .. Do something else here
return paths // This is a Promise because async functions always return a Promise
}
const findOneDoc = name => Product.findOne({ where: { name } }); // This func returns a Promise
const findAllDocs = product_id => Document.findAll({ // This func returns a Promise too
raw: true,
where: { product_id }
});
(async () => {
try {
const childProduct = await findOneDoc("some_name");
console.log("All good until now!");
const filePath = await findAllDocs(childProduct._id);
console.log("Still good");
const filteredFiles = await filterFiles(filePath);
console.log("All went well.");
console.log(filteredFiles);
} catch (err) {
// If any of the functions above fails, the try{} block will break and the error will be caught here.
console.log(`Error!`, err);
}
})();
There are few things I would like to mention.
When you create a promise, it should have resolve() and reject() inside it.
for ex-
function testPromise() {
return new Promise((resolve, reject) => {
// your logic
// The followin if-else is not nessesary, its just for an illustration
if (Success condition met) {
resolve(object you want to return);
}else {
reject(error);
// you can add error message in this error as well
}
});
}
// Calling the method with await
let obj = await testPromise()
// OR call with then, but its better to go with await
testPromise().then((obj)=>{
// Access obj here
})
In the method which you have written, You have applied .then() method to non promise object. You have to complete the promise block first with resolve() and reject() inside it. Then you can return that promise from a function, use it in async function Or apply .then() block on it.
Also you don't need to add return statement to resolve() and reject() statement. The system will take care of it.
You can also use try catch block inside a promise. Its better to write reject() statement in catch block, if anything goes wrong.

Javascript understanding promises

I've been using async with NodeJS, but I'm trying to understand the basic of promises in JavaScript and I'm having issues with it.
I created the code below for testing.
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second());
It should print '1' first, but it is printing '2' in the console first. Why is it happening?
Thanks
Two things:
first().then(second()) invokes second() immediately and passes its return value as the argument to then. You want to pass in the function itself, not its return value:
first().then(second); // no parens on second
And you're never resolving the first promise:
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
}
);
With those issues addressed it works as you'd intended:
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second);
There are a 2 problems in your code :
Your function first() returns a promise, but it isn't a promise in itself, so you cannot use the .then attribute on it.
You're not resolving anything in your 1st promise, you're just console.logging something, which is not something you can "wait" for.
What you're looking for is more something like this :
let first = new Promise((resolve) => {
setTimeout( function() {
console.log("1");
resolve(true); //you return your response, for example a boolean
}, 500)
})
function second(){
console.log("2");
}
first.then(response => {
//this is usually where you do something with the response
second();
});
Use Async Await
(as ray write) In new Promise() You must return resolve() or reject()
You can also use await:
function first() {
return new Promise(res => {
console.log(1);
return setTimeout(res, 500);
})
}
function second() {
console.log(2);
}
(async () => {
await first();
second();
})();

Why do you need to use .then() methods with javascript Promises?

New to Web Dev and learning Javascript.
Ive been following a tutorial on Promises, to try and understand what they are used for and what is so useful about them, and I came across this code:
var isMomHappy = true;
// Promise
var willIGetNewPhone = new Promise(
function (resolve, reject) {
if (isMomHappy) {
var phone = {
brand: 'Samsung',
color: 'black'
};
resolve(phone);
} else {
var reason = new Error('mom is not happy');
reject(reason);
}
}
);
//call our promise
var askMom = function () {
willIGetNewPhone
.then(function (fulfilled) {
// yay, you got a new phone
console.log(fulfilled);
})
.catch(function (error) {
// ops, mom don't buy it
console.log(error.message);
});
}
askMom();
Why is the .then() method needed when calling and handling the promise?
Can I not just do the following:
var isMomHappy = false;
// Promise
var willIGetNewPhone = new Promise(
function (resolve, reject) {
if (isMomHappy) {
var phone = {
brand: 'Samsung',
color: 'black'
};
resolve(phone);
console.log(phone);
} else {
var reason = new Error('mom is not happy');
reject(reason);
console.log(reason.message);
}
}
)
willIGetNewPhone;
...as this seems to reproduce the same results?
Thanks,
Stu
Your example just doesn't represent the real deal here. A promise is useful when e.g. you deal with data that needs to load first.
Here is another example (that is still gibberish and not 100% what you do for real)
const myPromise = new Promise((resolve) => {
setTimeout(
() => resolve('hello promise'),
1000
);
});
myPromise.then((data) => console.log(data));
console.log('This is called after then, yet it was executed before the promise resolved');
As you can see, you don't have the data, that is resolved by the promise straight away, but need to wait for a second. Imagine, you try to get data from the server. It won't be available straight away. So instead, you need to wait until it is resolved.
With ES7, there is another syntax which might make it a bit more clear: async/await:
const myPromise = new Promise((resolve) => {
setTimeout(
() => resolve('hello promise'),
1000
);
});
const init = async() => {
const data = await myPromise; // wait until promise has resolved
console.log(data);
console.log('Now the code flow is "correct" in the readers view')
};
init();
The then method returns a Promise which allows for method chaining.
If the function passed as handler to then returns a Promise, an equivalent Promise will be exposed to the subsequent then in the method chain.
See it on the docs for more detail.
In a very simple term (speaking language):
Go to the restaurant (promise succeeded)
Then, have some refreshment.
If you don't (promise failed)
Then, you'll miss enjoyment.
the .then((result)=>{}) is asking for the promises value to be passed into the function.
Your promise example is a bit terrible, so here is a more relevant example
const doingStuff=new Promise(function(resolve, reject){
setTimeout(function(){
resolve('hello world');
}, 10000);
});
doingStuff.then(function(result){
console.log(result);
});
console.log('after hello world');
The callback in the .then is called with the timeout finishes. That's async. It also means your function in the timeout is no longer anonymous, if it errors, promises will clearly show the doingStuff promise errored.
If you run this, your console will say
after hello world
hello world
Backwards, that's because your then ran after 10 seconds, even though it appeared first in code.
If you try this code, the error will happen before the resolve.
const doingStuff=new Promise(function(resolve, reject){
setTimeout(function(){
resolve('hello world');
}, 10000);
setTimeout(function(){
reject(new Error('Something went wrong'));
},5000);
});
doingStuff.then(function(result){
console.log(result);
});
console.log('after hello world');
Your console log will show the exact location this went wrong. And even better, you can handle the error later, the promise will hold onto the error until your ready using .catch(function(e){});.
const doingStuff=new Promise(function(resolve, reject){
setTimeout(function(){
resolve('hello world');
}, 10000);
setTimeout(function(){
reject(new Error('Something went wrong'));
},5000);
});
doingStuff.then(function(result){
console.log(result);
}).catch(function(e){
console.log('Error message:', e.message);
});
console.log('after hello world');

How to resolve Web3 promises objects? [duplicate]

Im trying to use async await on a function that returns a promise but the out put im getting is Promise { <pending> }. In here im using function called convertFiletoPDF which returns a promise. I need to get the output (the path that i have mention in resolve() ).
When i use it as
convertFiletoPDF(file).then((result) => {
console.log(result);
}).catch((err)=>{
console.log(err);
});
it gives the expected result.Whats wrong with the code below? im quite new to these async await and promises.
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
unoconv.convert(file, "pdf", function(
err,
result
) {
if (err) {
reject(err);
}
let File = file.substring(file.lastIndexOf("/")+1,file.lastIndexOf("."));
// result is returned as a Buffer
fs.writeFile(__dirname+"/files/converted/"+File+".pdf", result, error => {
/* handle error */
if (err) reject(error);
else resolve("./files/converted/"+File+".pdf");
});
});
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
let res = myfunc(file);
console.log(res);
The return value of an async function is a promise, so naturally that's what your console.log outputs. You need to either consume the result via await (within another async function) or use then/catch (within another async function).
This is what you're currently doing:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
let res = myfunc("some file");
console.log(res);
You need to be doing either this:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
(async() => {
try {
let res = await myfunc("some file");
console.log(res);
} catch (e) {
// Deal with the fact there was an error
}
})();
or with then and catch:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
myfunc("some file")
.then(res => {
console.log(res);
})
.catch(e => {
// Deal with the fact there was an error
});
convertFiletoPDF()
This function run and returned a Promise. This is fine.
myfunc()
Lets say myfunc takes 10 seconds. Javascript starts to wait newly created thread result from libuv via event loop mechanism. So, Javascript says, "That one is async, I will not wait, when it finishes it will let me know and i will run my then callback and then I will proceed with its output."
Javascript keeps his promise. Tries to run next below lines. myFunch is still working. Output is not ready yet. Returns undefined.
let res = myfunc(file);
console.log(res);
You get undefined.
Someone might find this example from my code useful. You can wrap it in a promise and then resolve the custom promise and then call another promise to confirm the receipt of the original web3 call.
return new Promise((resolve, reject) => {
tokenContract.methods.approve(
exchangeAddress,
BIG_NUMBER_1e50
)
.send({ from })
.once('transactionHash')
.once('receipt', receipt => resolve(receipt))
.on('confirmation')
.on('error', err => reject(err))
.then( receipt => // will be fired once the receipt its mined
console.log(receipt),
);
});

Using async await on custom promise

Im trying to use async await on a function that returns a promise but the out put im getting is Promise { <pending> }. In here im using function called convertFiletoPDF which returns a promise. I need to get the output (the path that i have mention in resolve() ).
When i use it as
convertFiletoPDF(file).then((result) => {
console.log(result);
}).catch((err)=>{
console.log(err);
});
it gives the expected result.Whats wrong with the code below? im quite new to these async await and promises.
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
unoconv.convert(file, "pdf", function(
err,
result
) {
if (err) {
reject(err);
}
let File = file.substring(file.lastIndexOf("/")+1,file.lastIndexOf("."));
// result is returned as a Buffer
fs.writeFile(__dirname+"/files/converted/"+File+".pdf", result, error => {
/* handle error */
if (err) reject(error);
else resolve("./files/converted/"+File+".pdf");
});
});
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
let res = myfunc(file);
console.log(res);
The return value of an async function is a promise, so naturally that's what your console.log outputs. You need to either consume the result via await (within another async function) or use then/catch (within another async function).
This is what you're currently doing:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
let res = myfunc("some file");
console.log(res);
You need to be doing either this:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
(async() => {
try {
let res = await myfunc("some file");
console.log(res);
} catch (e) {
// Deal with the fact there was an error
}
})();
or with then and catch:
function convertFiletoPDF(file) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 400, "Done");
});
}
async function myfunc(file){
let res = await convertFiletoPDF(file);
return res;
}
myfunc("some file")
.then(res => {
console.log(res);
})
.catch(e => {
// Deal with the fact there was an error
});
convertFiletoPDF()
This function run and returned a Promise. This is fine.
myfunc()
Lets say myfunc takes 10 seconds. Javascript starts to wait newly created thread result from libuv via event loop mechanism. So, Javascript says, "That one is async, I will not wait, when it finishes it will let me know and i will run my then callback and then I will proceed with its output."
Javascript keeps his promise. Tries to run next below lines. myFunch is still working. Output is not ready yet. Returns undefined.
let res = myfunc(file);
console.log(res);
You get undefined.
Someone might find this example from my code useful. You can wrap it in a promise and then resolve the custom promise and then call another promise to confirm the receipt of the original web3 call.
return new Promise((resolve, reject) => {
tokenContract.methods.approve(
exchangeAddress,
BIG_NUMBER_1e50
)
.send({ from })
.once('transactionHash')
.once('receipt', receipt => resolve(receipt))
.on('confirmation')
.on('error', err => reject(err))
.then( receipt => // will be fired once the receipt its mined
console.log(receipt),
);
});

Categories

Resources