Why should a Promise not be async? And how do I have to change this function?
With this I'm handling some files using gridFS and it is working as expected. But now I got the linting error not to use async promises. If I remove async, the function is not working anymore.
export async function getFiles () {
await db.connect()
const Images = db.gfs
return new Promise(async function (resolve, reject) { // <-- linting error
Images
.find()
.toArray((err, files) => {
if (err) reject(Error(err))
else if (!files) reject(Error('Failed to retrieve pending files'))
if (anyCondition) { resolve(something) }
else { resolve(files.filter(file => !file.metadata)) }
})
})
}
This would work with some function modularization:
async function otherGetFiles(){
await db.connect();
return await getFiles (db);
}
export function getFiles (db) {
const Images = db.gfs
return new Promise(async function (resolve, reject) {
Images
.find()
.toArray((err, files) => {
if (err) reject(Error(err))
else if (!files) reject(Error('Failed to retrieve pending files'))
// do some things here...
resolve(files.filter(file => !file.metadata))
})
})
}
Please try this code. This would work without any errors or warnings.
export async function getFiles() {
await db.connect()
const Images = db.gfs
return await new Promise(function (resolve, reject) {
Images
.find()
.toArray((err, files) => {
if (err) reject(Error(err))
else if (!files) reject(Error('Failed to retrieve pending files'))
// do some things here...
resolve(files.filter(file => !file.metadata))
})
})
}
Related
I'm trying to use async/await for a very basic promise, but I'm getting the error: SyntaxError: await is only valid in async function. However, I believe I'm using await for an async function.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = async (x) => await Promise.resolve(getNumber(x))
const val = await calculate(2)
You cannot have the initial function with an await at the top level... just a modification.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = (x) => Promise.resolve(getNumber(x));
const val = calculate(2).then(resp => {
console.log('do something with response: ', resp)
})
To only focus on why you're getting that error, the await in await calculate(2) isn't in an asynchronous function. If you can make it asynchronous function then do that but if not then you can use the .then() function like below:
calculate(2).then(val => {
//Your code here
}
In my loop I have to get the address of lat and long. I have this function using reverseGeolocation
_getLocationAddress = async location => {
return new Promise((resolve, reject) => {
try {
const { status, data } = await srs.getReverseGeolocation(location);
if (data) {
resolve(data.results[0].formatted_address);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
I also tried not wrapping into promise and not async it doesn't work it keeps returning a promise object. What I need from there is to return the data result into string. Here's my render
renderNewSR() {
const { delivery_items } = this.state;
return delivery_items.map((prop, key) => {
const location = {
latitude: parseFloat(prop.pickuplat),
longitude: parseFloat(prop.pickuplong)
};
//console.log(location);
const address = "";
this._getLocationAddress(location)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
.....
What is alternative solution to this. I want the result from google api return as string and can be displayed in render.
You are not declaring arrow function async inside new Promise but you are trying to use await inside that function.
Just add async (resolve, reject) to solve the issue.
Also you don't need to use async in async location as you are not awaiting any promise but returning promise in wrapper function.
_getLocationAddress = async location => {
return new Promise(async (resolve, reject) => {
try {
const { status, data } = await srs.getReverseGeolocation(location);
if (data) {
resolve(data.results[0].formatted_address);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
Hope that helps!!!
I have this following piece of code
new Promise((resolve, reject) => {
resolve(apiRequest(data))
reject(console.log('Error'))
}).then(response)
Both methods (resolve and reject) are being fired but I want to call reject only when something goes wrong.
How can I throw an error if something goes wrong on that case?
I checked that but it seems like I can not use an If statement to do that check.
new Promise((resolve, reject) => {
const printResult = apiRequest(data)
console.log(printResult) //Outputs Promise {<pending>}
resolve(printResult) //Then it works
reject(console.log('Error'))
}).then(response)
What would be the correct approach to reject a promise?
The easiest way would be with an if condition. i.e
new Promise((resolve, reject) => {
// do something...
if(somethingGoodHappened) {
resolve(data)
} else {
reject(error)
}
})
But usually when dealing with async requests, the thing you are calling will often be returning a promise, so you can attach the then and catch callbacks there.
apiRequest(data)
.then((result) => {
// all good
})
.catch((err) => {
console.log(err)
})
const mock_api = () => new Promise((res, rej) => {
const number = Math.floor((Math.random() * 100) + 1);
setTimeout(() => {
if (number%2==0) return res('randomly RESOLVED')
return rej('randomly REJECTED')
}, 2000)
})
const async_promise = () => new Promise(async (resolve, reject) => {
try {
const resolvedPromise = await mock_api()
resolve(resolvedPromise)
} catch (e) {
reject(e)
}
})
const classicPromise = () => new Promise((resolve, reject) => {
mock_api()
.then(resolve)
.catch(reject)
})
const makeAsyncRequest = async () => {
try {
const data = await async_promise()
console.log('ASYNC AWAIT RESOLVE', data)
} catch (e) {
console.log('ASYNC AWAIT ERR', e)
}
}
makeAsyncRequest()
classicPromise()
.then(r => console.log('PROMISE CHAIN RESOLVE', r))
.catch(e => console.log('PROMISE CHAIN ERR', e))
Because of you resolve before reject so it cannot run into reject,
You can use:
if (printResult) {
resolve(printResult)
} else {
reject(console.log('Error'))
}
You can catch exceptions and return them as rejected Promises
function asyncFunc() {
try {
doSomethingSync();
return doSomethingAsync()
.then(result => {
ยทยทยท
});
} catch (err) {
return Promise.reject(err);
}
}
Always check for err if there is any err return a promise (example below)
// Return new promise
return new Promise(function(resolve, reject) {
// Do async job
request.get(options, function(err, resp, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
})
})
I have a convoluted system, which totally works on async/await. What I want is to handle multiple types of errors from an async function in one and only try/catch block. Which means that I call this function from another async function.
But the concept of handling exceptions in a parent async function seems to fail. In the below example what I get - is just a warning about unhandled promise rejection, and the catch block in the parent won't ever get an error. I've tried this also with simply throwing and error, but unsuccessfully either.
const die = (word) => new Promise((resolve, reject) => reject(word));
const live = () => new Promise((resolve, reject) => resolve(true));
const daughterAsync = async () => {
await live();
try {
await die('bye');
} catch (err) {
return Promise.reject(err);
}
try {
await die('have a beatiful time');
} catch (err) {
return Promise.reject(err);
}
await live();
};
const parentAsync = async () => {
try {
daughterAsync();
} catch(err) {
console.log('error catched'); // never happens
console.log(err);
}
};
parentAsync();
I have a feeling that I don't get something about async functions to perform such a stunt
Your daughterAsync(); line only starts the promise running, but it doesn't save the reference to it or wait for it to resolve. You need to await the promise returned by daughterAsync inside of parentAsync's try block in order to catch errors in daughterAsync:
const die = (word) => new Promise((resolve, reject) => reject(word));
const live = () => new Promise((resolve, reject) => resolve(true));
const daughterAsync = async () => {
await live();
try {
await die('bye');
} catch (err) {
return Promise.reject(err);
}
try {
await die('have a beatiful time');
} catch (err) {
return Promise.reject(err);
}
await live();
};
const parentAsync = async () => {
try {
await daughterAsync();
} catch(err) {
console.log('error catched');
console.log(err);
}
};
parentAsync();
how can i use multi promise await in my codes ? when i wanna use second await for second promise it throw an error
function ReadJSONFile() {
return new Promise((resolve, reject) => {
fs.readFile('import.json', 'utf-8', (err, data) => {
if (err) reject(err);
resolve(JSON.parse(data));
});
});
}
const Get_Image = async (Path) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
return new Promise((resolve,reject) => {
resolve(stdout);
});
}
const Catch = async () => {
let get_json_file = await ReadJSONFile(); // this works perefectly
for(var i=0;i< Object.keys(get_json_file);i++) {
console.log(await Get_Image(get_json_file[i].image_path); //but this throw error
}
}
you didn`t return a promise that is why you got an error
const Get_Image = async (Path) => {
return new Promise((resolve,reject) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
resolve(stdout);
});
});
}