Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当执行在遇到返回之前到达块的末尾时,在解析承诺块中会发生什么?_Javascript_Parse Platform_Promise_Parse Cloud Code - Fatal编程技术网

Javascript 当执行在遇到返回之前到达块的末尾时,在解析承诺块中会发生什么?

Javascript 当执行在遇到返回之前到达块的末尾时,在解析承诺块中会发生什么?,javascript,parse-platform,promise,parse-cloud-code,Javascript,Parse Platform,Promise,Parse Cloud Code,假设我有以下解析云代码: // 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

假设我有以下解析云代码:

// 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(
  ...
…但有些函数不返回承诺,因此有时您别无选择,只能将主干样式的成功/错误块与承诺混合使用。)

我的问题:

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


换句话说,是否有可能按C、D、A/B顺序执行?还是总是C、A/B、D?(或者,我想,如果save完成得非常快,比如A/B、C、D?

您的
返回值
来自内部函数。如果由我决定,我会保证
save
函数本身。但是,如果您确信不想这样做,您仍然必须从
返回
Parse.Promise
,然后如果您希望它等待任何操作,则必须返回
Parse.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方法已经返回了一个承诺-Parse promisified it for us-因此这段代码可以显著减少为:

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
});   
这反过来又可以简化为:

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

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


在任何情况下,调用异步代码(就像我对save()所做的那样)但不在then函数块的末尾显式返回本地承诺,这基本上是一个bug——尽管运行时不会抱怨这个bug——这会使更大的承诺等待异步代码完成。换句话说,我应该像本杰明·格伦鲍姆的回答所建议的那样做。

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

此外,根据每个区块中所需的范围不同,您如何返回承诺也会有所不同

例如:

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

在使用回调API时,您需要。您的返回在那些
success
error
函数中,而不是在
then
中。删除了我的答案,因为它实际上取决于在解析API中如何准确地实现
Promise
。如果它遵循PromiseA的建议,是的,一个新的承诺将被返回-操作顺序变得模糊。谢谢,raina770w,我喜欢你的回答!不知道Parse.Promise是否遵循rec.Benjamin Gruenbaum,我在理论上不能不转换为promises,而是直接转换为:Promise=new Parse.Promise();在C,返回承诺;在A和B,一定要保证。解决()?我很确定我能做到这一点,它将完美地工作。。。完全信守诺言也许是明智的,但我认为你不需要这样做。承诺有缺点,至少是Parse.Promise,例如需要区分不同错误原因的情况。您可以区分错误原因。您需要转换正在使用的函数。让我写一个答案。谢谢!仅供参考,我没有将代码分解为更简洁的promise-y代码的部分原因是我希望在不同情况下保持灵活性。。。例如,可能我想在保存失败时增加一个计数器。相关问题:在处理承诺错误/拒绝时,到达函数(错误)块末尾后会发生什么?我知道,如果它返回一个解析或拒绝的承诺,它的行为就像一个常规的then function()块。如果它没有返回任何内容,它会继续执行next then()吗?有没有办法从那一点中止承诺链的执行?@BenjaminWheeler你可以实现一个计数器,在拒绝处理程序中增加它。承诺拒绝处理程序与捕获处理程序完全相同,
处理程序将从该点开始运行(恢复)。如果你想中止一个链,就不要捕捉错误——在链的末尾处理它。我不明白。我不能“抓住”这个错误,如果中间有任何函数(错误),在那里有一个不同的错误…不清楚计数器会有什么帮助,尽管像firstSaveFailed、secondSaveFailed等明显不同的变量会起作用(但太笨拙了,会让我想回到成功/错误块!)请看我的后续问题:@BenjaminGruenbaum,作为一名专家,你可能对这个可能更简单的问题有自己的看法。。我真是受不了。。THX为什么您的代码嵌套在5个级别?为什么oyu有多余的
Parse.promise.as
,为什么返回
Parse.promise.as(a)
?这只是嵌套承诺的一个例子,不是代码应该如何编写。此外,您需要将范围传递给下一个承诺,该承诺将传递给bowie Function。这很有帮助,但我不完全清楚它与我的问题的关系。是的。如果您有一些异步的东西需要等待,那么您需要为它返回一个承诺。如果忘记了return语句,