如何使解析查找/保存操作同步?

时间:2016-11-02 13:34:28

标签: javascript node.js parse-platform promise parse-javascript-sdk

我们在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操作成功/完成时返回?

2 个答案:

答案 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);

此外,您可以使用promisesgenerators(自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)
        })  
 }