1

假设我有以下 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
});

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

myObj.save().then(
  ...

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

我的问题:

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

换句话说,是否可以按照 C、D、A/B 的顺序执行?还是永远是 C、A/B、D?(或者,我想,如果保存完成得很快,比如 A/B、C、D?)

4

3 回答 3

3

returns来自内部功能。如果由我决定,我会承诺save功能本身。然而,如果你确信你不想这样做,你仍然必须Parse.Promise从 a 返回,then如果你想让它等待任何东西。

该函数返回一个新的 Promise 并在其返回值then被解析时解析该 Promise(进一步执行)。如果这只是一个值,它不会等待任何东西 - 如果它是一个承诺,它会等待它依次解决。

请查看如何承诺以供进一步阅读。

在您的示例中 - 这看起来像:

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 的 save 方法已经返回了一个 Promise - 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
});   
于 2014-09-12T17:41:51.120 回答
0

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

在任何情况下,调用异步代码(就像我使用 save() 所做的那样)基本上是一个错误——尽管运行时不会抱怨——但没有在 then 函数块的末尾显式返回本地承诺,这将做出更大的承诺,直到异步代码完成。换句话说,我应该做 Benjamin Gruenbaum 的回答建议的事情。

于 2014-09-12T19:28:25.940 回答
0

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

此外,您返回 Promise 的方式取决于每个块所需的范围。

例如:

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
})
于 2014-09-12T20:16:25.783 回答