如何使 parse find/save 操作同步?
How to make parse find/save operations synchronous?
我们正在用 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() 功能 returns 只有当 find/first 操作是 successful/complete?
JavaScript 本质上是异步的。您必须将回调传递给 fetchUser()
函数并将您的客户端代码重写为如下内容:
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);
}
您也可以使用 promises or generators(自 EcmaScript 6 起)方法。
UPD: 尽管一些 APIs(DB 驱动程序、fs 等)允许以同步方式使用它们,但它被认为是一种不好的方式在JavaScript中写一段代码。由于 JS 在单线程中运行您的代码,使用同步调用阻塞此线程将阻塞所有其他任务。因此,如果您开发一个同时处理几个客户端的 Web 服务器并决定对一些 API 使用同步调用,则一次只会为一个客户端提供服务,而其他客户端将处于挂起状态。
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:使用 Promising 库
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)
})
}
我们正在用 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() 功能 returns 只有当 find/first 操作是 successful/complete?
JavaScript 本质上是异步的。您必须将回调传递给 fetchUser()
函数并将您的客户端代码重写为如下内容:
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);
}
您也可以使用 promises or generators(自 EcmaScript 6 起)方法。
UPD: 尽管一些 APIs(DB 驱动程序、fs 等)允许以同步方式使用它们,但它被认为是一种不好的方式在JavaScript中写一段代码。由于 JS 在单线程中运行您的代码,使用同步调用阻塞此线程将阻塞所有其他任务。因此,如果您开发一个同时处理几个客户端的 Web 服务器并决定对一些 API 使用同步调用,则一次只会为一个客户端提供服务,而其他客户端将处于挂起状态。
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:使用 Promising 库
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)
})
}