We are writing server code in nodejs and using Parse javascript sdk. Often we need to fetch or update various Parse objects. For example, fetch a user with username 'Example'.
function fetchUser(username)
{
var User = Parse.Object.extend("User");
var query = new Parse.Query("User");
query.equalTo("username",username);
query.first({
success: function(results) {
console.log("Successfully retrieved " + results.length + " scores.");
return results;
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
}
This function might be called by some other function:
function test()
{
var user = fetchUser("example");
console.log(user); // would often print undefined
return user;
}
function top()
{
// some code
var user = test();
//some code
}
// and the function top() mmight be called by some other functions
The problem is that I would get undefined results because the find/first operations runs asynchronously. Is there any way to ensure that fetchUser() function returns only when the find/first operation is successful/plete?
We are writing server code in nodejs and using Parse javascript sdk. Often we need to fetch or update various Parse objects. For example, fetch a user with username 'Example'.
function fetchUser(username)
{
var User = Parse.Object.extend("User");
var query = new Parse.Query("User");
query.equalTo("username",username);
query.first({
success: function(results) {
console.log("Successfully retrieved " + results.length + " scores.");
return results;
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
}
This function might be called by some other function:
function test()
{
var user = fetchUser("example");
console.log(user); // would often print undefined
return user;
}
function top()
{
// some code
var user = test();
//some code
}
// and the function top() mmight be called by some other functions
The problem is that I would get undefined results because the find/first operations runs asynchronously. Is there any way to ensure that fetchUser() function returns only when the find/first operation is successful/plete?
Share Improve this question asked Nov 2, 2016 at 13:34 PaagalpanPaagalpan 1,3212 gold badges17 silver badges28 bronze badges 3- why don't you just provide a callback to fetchUser and test? If you want to have a better readable code use promises instead of callbacks. – Tobi Commented Nov 2, 2016 at 13:38
- 2 You can't make async operations be synchronous. Cannot be done in Javascript. Stop trying. Learn how to program asynchronously with callbacks or promises or switch to a blocking/threaded environment like Java that lets you do things like this blocking/synchronously in threads (with the associated promises of that architecture). – jfriend00 Commented Nov 2, 2016 at 17:36
- Really new to javascript. Sometimes, simply a 'just not possible' is also a good enough response. Thanks. :) – Paagalpan Commented Nov 3, 2016 at 11:20
2 Answers
Reset to default 5JavaScript is asynchronous by its nature. You have to pass a callback to the fetchUser()
function and rewrite your client code to something like this:
function fetchUser(username, callback) {
// do request and call callback(null, user) on success
// or callback(some_error_object) on failure.
}
function test(callback) {
var onFetched = function(err, user) {
console.log(user);
callback(err, user);
}
var user = fetchUser("example", onFetched);
}
Also you can use promises or generators (since EcmaScript 6) approaches.
UPD: Although some APIs (DB drivers, fs and so on) allow one to use them in a synchronous manner, it's considered as bad way to write a code in JavaScript. Since JS runs your code in a single thread, blocking this thread by using synchronous calls will block all other tasks. So, if you develop a web server that handles a few clients simultaneously and decided to use synchronous calls to some API, only one client at a time will be served while other clients will be in a pending state.
NodeJs is single threaded, so we should not block process.
in your case you have two options 1. passing callback 2. using Promise library (https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
Ex 1: passing callback
function fetchUser(username, callback)
{
var User = Parse.Object.extend("User");
var query = new Parse.Query("User");
query.equalTo("username",username);
query.first({
success: function(results) {
console.log("Successfully retrieved " + results.length + " scores.");
callback(null,results)
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
callback(error)
}
});
}
Client code:
function test()
{
var user = fetchUser("example", function(error, user){
if(error){
console.error(error)
}else {
console.log(user)
}
});
}
Ex 2: Using Promising library
function fetchUser(username){
return new Promise(function(resolve, reject){
var User = Parse.Object.extend("User");
var query = new Parse.Query("User");
query.equalTo("username",username);
query.first({
success: function(results) {
console.log("Successfully retrieved " + results.length + " scores.");
resolve(results)
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
reject(error)
}
});
})
}
Client code:
function test()
{
fetchUser("example")
.then(function(user){
console.log(user)
})
.catch(function(error){
console.error(error)
})
}