【问题标题】:How to make parse find/save operations synchronous?如何使解析查找/保存操作同步?
【发布时间】:2016-11-02 21:56:48
【问题描述】:

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

【问题讨论】:

  • 为什么不直接提供一个回调给 fetchUser 并进行测试呢?如果您想拥有更好的可读性代码,请使用 Promise 而不是回调。
  • 你不能让异步操作同步。无法在 Javascript 中完成。别再尝试了。了解如何使用回调或 Promise 进行异步编程,或切换到 Java 之类的阻塞/线程环境,让您可以在线程中以阻塞/同步的方式执行此类操作(以及该架构的相关妥协)。
  • JavaScript 的新手。有时,简单的“不可能”也是一个足够好的回应。谢谢。 :)

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


【解决方案1】:

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);
}

您也可以使用promisesgenerators(从 EcmaScript 6 开始)方法。

UPD:虽然某些 API(DB 驱动程序、fs 等)允许以同步方式使用它们,但在 JavaScript 中编写代码被认为是一种糟糕的方式。由于 JS 在单个线程中运行您的代码,因此使用同步调用阻塞该线程将阻塞所有其他任务。因此,如果您开发一个同时处理几个客户端的 Web 服务器,并决定对某些 API 使用同步调用,那么一次只会为一个客户端提供服务,而其他客户端将处于挂起状态。

【讨论】:

  • 非常感谢您的回复和很好的例子。更新真的很有帮助。那谢谢啦。我无法决定接受哪个答案,但选择了另一个答案,因为它也有一个承诺的例子。对不起。
【解决方案2】:

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)
        })  
 }

【讨论】:

  • 感谢您提供这两种情况的详细示例。 :)
  • Parse Queries 返回一个 Parse.Promise,它几乎完全符合 Promises/A+ - 所以你不必将它包装在另一个 Promise 库中......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 2011-04-11
相关资源
最近更新 更多