在遇到返回之前执行到达块结尾时,Parse Promise中会发生什么阻塞?

时间:2014-09-12 17:04:32

标签: javascript parse-platform promise cloud-code

假设我有以下Parse云代码:

// assume myObj is a parse object
myObj.set("field1", "foo");
Parse.Promise.as().then(function() 
  myObj.save(myObj, {
    success: function(savedObj) {
      // A
      return Parse.Promise.as();
    },
    error: function(myObj, error) {
      // B
      return Parse.Promise.as();
    }
  });
  // C
  // note that we can get here without any return statement being called
}).then(function() {
  // D
});

(现在,我知道对整个事情使用承诺会更简单:

myObj.save().then(
  ...

...但是有一些函数不会返回promises,所以有时你别无选择,只能将Backbone风格的成功/错误块与promises混合使用。)

我的问题:

到达C后会发生什么? 执行会暂停此承诺,直到达到其中一个返回语句,然后执行达到D?达到C后执行是否直接进入D,而不等待返回语句?这是错误吗?

换句话说,执行是否可能以C,D,A / B的顺序发生?或者它总是C,A / B,D? (或者,我想,如果保存快速结束,比如A / B,C,D?)

3 个答案:

答案 0 :(得分:3)

您的returns来自内部功能。如果由我决定,我会宣传save功能本身。但是,如果您确信自己不想这样做,那么如果您希望它等待任何事情,您仍需要从Parse.Promise返回then

then函数返回一个新的promise,并在解析返回值时解析该promise(进一步执行thens)。如果这只是一个值,它将不会等待任何事情 - 如果它是一个承诺,它将等待它反过来解决。

请查看how to promisify以便进一步阅读。

在你的例子中 - 这看起来像是:

myObj.set("field1", "foo");
Parse.Promise.as().then(function(){
  var p = Parse.Promise();
  myObj.save(myObj, {
    success: p.resolve.bind(p), // on success, resolve the promise
    error: p.reject.bind(p) // on failure, reject it
  });
  // any code here _will_ execute before the `then` is called.
  return p; // return the promise so `then` will wait
}).then(function(savedObj) {
    // this will always run after `myObj.save` completed
    // you can add a catch handler for the error case
});

但是,如果我们注意,我们可以注意到Parse的保存方法已经返回一个承诺 - Parse为我们宣传 - 所以这段代码可以大大简化为:

myObj.set("field1", "foo");
Parse.Promise.as().then(function(){

  return myObj.save(myObj)
}).then(function(savedObj) {
  // this will always run after `myObj.save` completed
  // you can add a catch handler for the error case
});

反过来可以简化为:

myObj.set("field1", "foo");
myObj.save().then(function(savedObj){
   // object save is done here
});   

答案 1 :(得分:0)

答案似乎是它不会等待A或B - 它会继续前进,可能是D在A或B之前执行。

在任何情况下,它基本上都是一个错误 - 虽然不是运行时会抱怨的 - 调用异步代码(就像我使用save())但是没有在then函数结束时显式返回本地promise阻塞将使更大的承诺等到异步代码完成。换句话说,我应该做像Benjamin Gruenbaum的答案所说的那样。

答案 2 :(得分:0)

根据经验,只要继续回复承诺,它们将自动解决。所有Parse异步方法都返回promises,所以只要你完成就继续返回。 我不建议使用successerror方法。一起使用回调和承诺不是一个好主意,因为你必须编写大量额外的代码来解释它。如果你的应用程序中的所有内容都返回promises,你可以很容易地删除一个块或添加另一个块。只需创建返回承诺的函数。

此外,您如何根据每个区块所需的范围而返回承诺。

例如:

function myPromise (a) {
  return Parse.Promise.as({name: 'David Bowie', a : a});
}

myObj.set("a", 1);

myObj.save(obj).then(function(obj) {
  var a = obj.get('a');
  return Parse.Promise.as()
    .then(function() {
      return Parse.Object.saveAll([])
        .then(function() {
          a += 1
          return Parse.Promise.as(a);
      })
    })
}).then(function(a){
  return myPromise(a);
})
.then(function(davidBowie) {
  console.log(davidBowie.name);
  console.log(davidBowie.a);
})
.fail(function() {
  // handle error
})