admin管理员组文章数量:1289868
I have this scenario:
app.get('/', async function (request, response)
{
await foo(DbConnection).then((result) => console.log("response ready"));
})
let foo = async function (DbConnection)
{
const myQuery = "SELECT * FROM my_table";
DbConnection.query(myQuery, async function(err, results) {
console.log("query ready");
await bar(results).then((response) => console.log("bar done"))
})
return; // go back to app.get() to send stuff to client
}
let bar = async function (results)
{
console.log("inside bar");
await ThirdPartyAPI(result).then((value)) => return value);
}
Briefly:
I receive GET request from client
I call foo() which query data base and apply functions on results
I process results using third party API which takes time to finish
I send final results back to client
I am expecting to see:
query ready -> inside bar -> bar done -> response ready
But I instead see:
response ready -> query ready -> inside bar -> bar done
Client is receiving undefined
since nothing was ready when response.send()
What could be the issue?
I have this scenario:
app.get('/', async function (request, response)
{
await foo(DbConnection).then((result) => console.log("response ready"));
})
let foo = async function (DbConnection)
{
const myQuery = "SELECT * FROM my_table";
DbConnection.query(myQuery, async function(err, results) {
console.log("query ready");
await bar(results).then((response) => console.log("bar done"))
})
return; // go back to app.get() to send stuff to client
}
let bar = async function (results)
{
console.log("inside bar");
await ThirdPartyAPI(result).then((value)) => return value);
}
Briefly:
I receive GET request from client
I call foo() which query data base and apply functions on results
I process results using third party API which takes time to finish
I send final results back to client
I am expecting to see:
query ready -> inside bar -> bar done -> response ready
But I instead see:
response ready -> query ready -> inside bar -> bar done
Client is receiving undefined
since nothing was ready when response.send()
What could be the issue?
Share Improve this question edited Aug 21, 2017 at 17:12 Khalil Khalaf asked Aug 18, 2017 at 21:12 Khalil KhalafKhalil Khalaf 9,39712 gold badges67 silver badges108 bronze badges1 Answer
Reset to default 10The main problem in your code is that you're mixing async/await
syntax and callbacks. Use async
function only when you want to do something with the result of async call inside this function.
Also that, specific to your case, you need to promisify connection.query()
- create a promise. See below the correct pattern with a working code:
app.get('/', async (request, response) => {
// waiting for the result of foo
let result = await foo();
console.log("response ready");
});
let foo = async () => {
const myQuery = "SELECT * FROM my_table";
// getting the result of the query
let results = await new Promise((resolve, reject) => connection.query(myQuery, (err, results) => {
if (err) {
reject(err)
} else {
resolve(results);
}
}));
console.log("query ready");
// call bar and waiting the result
let res = await bar(results);
console.log("bar done");
// return resolved promise
return res;
}
let bar = (results) => {
console.log("inside bar");
// just return a promise, we don't need the result here
return ThirdPartyAPI(result);
}
Explanation about using async/await
. The power of async/await
is that it lets you write asynchronous code using synchronous language constructs. But that doesn't mean that all functions should be marked as async
. async
wraps a function into a promise, if the function executes synchronous code, this wrapping can cause an error (you expect the string for example, but function returns a resolved promise). Another example when the function executes async code, but doesn't use intermediate result, in this case it's enough just return the result of async call.
You should use async/await
when:
- The function executes sync code, and you want to wrap the result into a promise (for creating a promise chain).
- The function executes async code and you need an intermediate result.
- The function executes async code and you don't need an intermediate result, but you want execute code in series (for processing each item in array for example).
Let's consider some examples:
1.sync function, validates userId
. validateParams
returns true/false
, validateParams2
throws an error if userId
is undefined. validateParams3
returns a promise, and can be used for creating a promise chain: validateParams3().then(...)
.
let validateParams = (userId) => {
return userId;
}
let validateParams2 = (userId) => {
if (!userId) {
throw new Error('userId is undefined');
}
}
let validateParams3 = (userId) => {
if (!userId) {
return Promise.reject(new Error('userId is undefined'));
}
return Promise.resolve();
}
2.async function, doesn't use intermediate result. getUser
returns a pending promise (when userId
is valid) or fulfilled promise (when userId
is undefined). It should return a promise, because getUser
can be used for starting a promise chain: createUser().then(...)
. getUser2
and getUser3
do the same thing, return a promise. The promise is requred here to avoid getting unhandledError
error, because validateParams2
can throw an error. getUser2
makred as async
(to create a promise automatically), and getUser3
returns a promise.
let getUser = (userId) => {
if (validateParams(userId)) {
return db.getUserById(userId);
}
return Promise.resolve();
}
let getUser2 = async (userId) => {
validateParams2(userId);
return db.getUserById(userId);
}
let getUser3 = (userId) => {
return Promise
.resolve(userId)
.then(validateParams2)
.then(() => db.getUserById(userId);
}
3.async function, uses an intermediate result:
let updateUser = async (userId, userData) => {
let user = await getUser(userId);
_.extend(user, userData);
return db.saveUser(user);
}
The functions above can be used this way:
// with async
let fn = async (userId, userData) => {
try {
let user = await updateUser(userId, userData);
console.log(user);
}
catch (err) {
console.log(err);
}
}
// without async
let fn2 = (userId, userData) => {
updateUser(userId, userData)
.then(user => console.log(user))
.catch(err => console.log(err))
}
}
本文标签:
版权声明:本文标题:javascript - How to await for a function or a database query? And then process results and finally send them back - Stack Overfl 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741461920a2380086.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论