假设我有以下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?)
答案 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,所以只要你完成就继续返回。
我不建议使用success
和error
方法。一起使用回调和承诺不是一个好主意,因为你必须编写大量额外的代码来解释它。如果你的应用程序中的所有内容都返回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
})