我们在nodejs中编写服务器代码并使用Parse javascript sdk。我们经常需要获取或更新各种Parse对象。例如,使用用户名“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);
}
});
}
此功能可能由其他一些功能调用:
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
问题是我会得到未定义的结果,因为find / first操作是异步运行的。有没有办法确保fetchUser()函数仅在find / first操作成功/完成时返回?
答案 0 :(得分:5)
JavaScript本质上是异步的。您必须将回调传递给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);
}
函数并将您的客户端代码重写为以下内容:
typedef struct {
double minVal;
double maxVal;
} MIN_MAX_VALS;
MIN_MAX_VALS suurim(double arv[], int x, double *array)
{
MIN_MAX_VALS xValues;
int i;
double temp;
temp = arv[0];
for(i = 1; i < x; i++) // biggest
{
if (arv[i] > temp)
{
array[0] = arv[i];
}
}
for(i = 1; i < x; i++) // smallest
{
if (arv[i] < temp)
{
array[1] = arv[i];
}
}
xValues.minVal = array[0];
xValues.maxVal = array[1];
return xValues;
}
MIN_MAX_VALS result = suurim(arv, mituArvu, array);
printf("min:%0.1lf\n", result.minVal);
printf("max:%0.1lf\n", result.maxVal);
此外,您可以使用promises或generators(自EcmaScript 6开始)。
UPD:虽然有些API(数据库驱动程序,fs等)允许以同步方式使用它们,但它被认为是用JavaScript编写代码的糟糕方式。由于JS在单个线程中运行您的代码,因此使用同步调用阻止此线程将阻止所有其他任务。因此,如果您开发一个同时处理几个客户端并决定对某些API使用同步调用的Web服务器,则一次只能提供一个客户端,而其他客户端将处于挂起状态。
答案 1 :(得分:3)
NodeJs是单线程的,所以我们不应该阻止进程。
在您的情况下,您有两个选择 1.传递回调 2.使用Promise库(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
例1:传递回调
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)
}
});
}
客户代码:
function test()
{
var user = fetchUser("example", function(error, user){
if(error){
console.error(error)
}else {
console.log(user)
}
});
}
例2:使用有前途的库
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)
}
});
})
}
客户代码:
function test()
{
fetchUser("example")
.then(function(user){
console.log(user)
})
.catch(function(error){
console.error(error)
})
}