This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
Closed 5 years ago.
I am using couchbase ottaman package:
let transaction = new Transaction({name:'Couch'});
transaction.save((err) => {
console.log(err);
});
but can I use async/await with this package?
async create(){
let transaction = new Transaction({name:'Couch'});
try{
await transaction.save();
} catch (err) {
console.log(err);
}
}
I am getting error:
node_modules\ottoman\lib\modelinstance.js:457
callback(err);
^
TypeError: callback is not a function
Basically, you have to check if it returns promise - you can use it out of box. If not - you can promisify function you need.
Something like this in result:
function saveModel(transaction) {
return new Promise ((resolve, reject) => {
transaction.save(err => {
if (err)
reject(err);
else
resolve();
});
});
}
Such function can be used with async/await:
async create(){
let transaction = new Transaction({name:'Couch'});
try{
await saveModel(transaction);
} catch (err) {
console.log(err);
}
}
Another option is to view source files, but I'm too lazy to do it.
Related
This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
Closed 2 years ago.
I have the following code on a server:
let tmpFileName;
// GET
app.get('/clicked', async (req, res) => {
let nullOutput = writeTmpFile("hello, world!");
await deleteTmpFile();
console.log("Hurray, finished!");
res.send({result:nullOutput});
})
function writeTmpFile(content){
tmpFileName = "tmp" + Math.random().toString() + "tsl";
return new Promise(resolve => {
fs.writeFile(tmpFileName, content, function (err) {
if (err) throw err;
console.log('Temp file creation successful.');
});
})
}
function deleteTmpFile(spec){
return new Promise(resolve => {
fs.unlink(tmpFileName, function (err) {
if (err) throw err;
console.log('Temp file deletion successful.');
});
})
}
However, in my console output, I only get
Temp file creation successful.
Temp file deletion successful.
However, if I delete await deleteTempFile(), then Hurray, finished! shows up on the console.
And more generally, how do I debug these patterns of problems?
Why is this happening?
I have rewritten your code, to showcase how to use promises.
Promise callback gets two functions as arguments: resolve and reject.
You should call resolve when operation finishes with success, and reject when it fails.
// I moved `tmpFileName` variable from here into the request handler,
// because it was "global" and would be shared between requests.
app.get('/clicked', async (req, res) => {
let tmpFileName = "tmp" + Math.random().toString() + "tsl"
let writingResult = await writeTmpFile(tmpFileName, "hello, world!")
let deletionResult = await deleteTmpFile(tmpFileName)
res.send({ writingResult, deletionResult })
console.log("Hurray, finished!")
})
function writeTmpFile (filename, content) {
return new Promise((resolve, reject) => {
fs.writeFile(filename, content, function (err) {
// on error reject promise with value of your choice
if (err) reject(err)
// on success resolve promise with value of your choice
resolve('Temp file creation successful.')
})
})
}
function deleteTmpFile (filename) {
return new Promise((resolve, reject) => {
fs.unlink(filename, function (err) {
if (err) reject(err)
resolve('Temp file deletion successful.')
})
})
}
For working with the file you can use writeFileSync instead writeFile. (Reference).
For multiple Promise you can use the Promise.all method.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
from MDN
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have the following function at the moment, and I want to return "aaa" to the parent function (getStream), this is the code I have atm:
module.exports.getStream = (figure) => {
plotly.plot(figure, imgOpts, function(err, stream) {
if (err) {
console.log(err);
return "error";
}
return "aaa";
});
};
Right now, however, it returns undefined. What's the best solution to solve that problem?
The problem is that getStream does not return anything (therefore its return value is undefined). You have to add return before plotly or just remove curly braces. Also you'll have to return a promise, because that third argument of plotly.plot method is a callback function (I guess).
module.exports.getStream = (figure) =>
new Promise((resolve, reject) => {
plotly.plot(figure, imgOpts, function(err, stream) {
if (err) {
console.log(err);
reject("error");
}
resolve("aaa");
});
})
and then somewhere in the app:
const foo = async () => {
try {
const result = await getStream(figure)
console.log(result) // 'aaa'
} catch (err) {
console.log(err) // 'error'
}
}
This question already has answers here:
await is only valid in async function
(14 answers)
Closed 4 years ago.
I was trying to read a JSON file using Async/Await, I created my example based Native async/await approach, and I got this error.
SyntaxError: await is only valid in async function
Here is my code.
const fs = require('fs-extra');
const xml2js = require('xml2js');
const parser = new xml2js.Parser();
const path = "file.json";
function parseJM() {
return new Promise(function (resolve, reject) {
fs.readFile(path, { encoding: 'utf-8'}, (err, data) => {
if (err) { reject(err); }
else {
resolve (parser.parseString(data.replace(/<ent_seq>[0-9]*<\/ent_seq>/g, "")
.replace(/&(?!(?:apos|quot|[gl]t|amp);|#)/g, '')));
}
});
});
}
const var1 = await parseJM();
console.log(var1);
What is wrong with my code? My node version is 11.9.0, my npm version is 6.7.0 and i am using Arch Linux.
You need to call await inside an async function.
(async () => {
try {
const var1 = await parseJM();
console.log(var1);
} catch (e) {
console.error(e.message);
}
})();
Edit: As suggested by #Nik Kyriakides
The error itself is telling you exactly what the issue is. You can only await inside an async-marked function.
If that's your top-level code you can just use an async IIFE:
;(async () => {
try {
await doSomething()
} catch (err) {
console.error(err)
}
})()
or just then/catch it. async functions return a Promise after all:
doSomething()
.then(result => {
console.log(result)
})
.catch(err => {
console.error(err)
})
This question already has answers here:
How to turn this callback into a promise using async/await?
(2 answers)
How do I convert an existing callback API to promises?
(24 answers)
Closed 5 years ago.
I'm new to asynchronous programming,
I'm facing issue similar to this question, in this question suggested approach uses callbacks but I'm trying to do it using Promises and async-await functions. I get undefined in the console. Here's my example. what am I missing?
//Defining the function
async query( sql, args ) {
const rows = this.connection.query( sql, args, async( err, rows ) =>
{
if ( err )
throw new Error(err);
return rows;
} );
}
//calling the function here
db.query("select 1")
.then((row) => console.log("Rows",row)) // Rows undefined
.catch((e) => console.log(e));
make your query function return a Promise
function query(sql, args) {
return new Promise(function (resolve , reject) {
this.connection.query(sql, args, (err, rows) => {
if (err)
reject(err);
else
resolve(rows)
});
});
}
//calling the function here
query("select 1")
.then((row) => console.log("Rows",row)) // Rows undefined
.catch((e) => console.log(e));
This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
Closed 5 years ago.
Is there a way to deal with callback functions inside an async function() other than mixing in bluebird or return new Promise()?
Examples are fun...
Problem
async function bindClient () {
client.bind(LDAP_USER, LDAP_PASS, (err) => {
if (err) return log.fatal('LDAP Master Could Not Bind', err);
});
}
Solution
function bindClient () {
return new Promise((resolve, reject) => {
client.bind(LDAP_USER, LDAP_PASS, (err, bindInstance) => {
if (err) {
log.fatal('LDAP Master Could Not Bind', err);
return reject(err);
}
return resolve(bindInstance);
});
});
}
Is there a more elegant solution?
NodeJS v.8.x.x natively supports promisifying and async-await, so it's time to enjoy the stuff (:
const
promisify = require('util').promisify,
bindClient = promisify(client.bind);
let clientInstance; // defining variable in global scope
(async () => { // wrapping routine below to tell interpreter that it must pause (wait) for result
try {
clientInstance = await bindClient(LDAP_USER, LDAP_PASS);
}
catch(error) {
console.log('LDAP Master Could Not Bind. Error:', error);
}
})();
or just simply use co package and wait for native support of async-await:
const co = require('co');
co(function*() { // wrapping routine below to tell interpreter that it must pause (wait) for result
clientInstance = yield bindClient(LDAP_USER, LDAP_PASS);
if (!clientInstance) {
console.log('LDAP Master Could Not Bind');
}
});
P.S. async-await is syntactic sugar for generator-yield language construction.
Use modules! pify for instance
const pify = require('pify');
async function bindClient () {
let err = await pify(client.bind)(LDAP_USER, LDAP_PASS)
if (err) return log.fatal('LDAP Master Could Not Bind', err);
}
Haven't tested it yet