我担心 Parse 使用 jQuery 兼容的 Promise,因为我已经读过 jQuery Promise 允许消费者改变 Promise 的状态。
你不需要担心。“jQuery 兼容”可能意味着很多事情,Parse 承诺当然不允许消费者改变他们的状态1(因为 jQuery 多年来也没有这样做)。顺便说一句,它们也是 A+“兼容”的 :-)
1:通过公共方法。所以不超过大多数其他实现,也就是说。
是否可以使用已知与 Parse JavaScript SDK 兼容的 Promises/A+ 的另一个 Promise 实现?
是的。Parse SDK 确实返回了有效的 A+ thenables,这意味着您可以从then
您最喜欢的 Promise 实现的回调中返回 Parse Promise,并期望它可以完美地工作:
myCompliantPromise.then(function(res) {
return parse_query.get(…);
}).then(…)
您还可以使用 将它们转换为有效的实现承诺Promise.resolve
,例如:
Promise.resolve(parse_query.get(…)).then(…);
通常我会假设这是不可能的,但是在 Parse JavaScript SDK 的 v1.4.2 中,Parse.Promise 的实现定义了属性_isPromisesAPlusCompliant
,false
然后在库中的各种函数中检查该属性。
他!虽然不幸的是没有记录,但这个标志确实允许你在你的应用程序中使原生 Parse.com 承诺库 A+ 兼容:
Parse.Promise._isPromisesAPlusCompliant = true;
更新:在较新的版本中,这不会作为下划线属性公开,而是您必须调用(未记录的)Parse.Promise.enableAPlusCompliant()
方法。有关详细信息,请参阅问题 #57。
我已经查看了代码,这个标志基本上改变了 3 件事:
- 回调中的异常
then
被捕获并导致结果承诺被拒绝,而不是全局错误。所以你可以throw
在它们中使用。
- 如果你
return
从onRejected
回调(第二个参数then
)的值,错误应该被处理,结果承诺被履行而不是被拒绝。
- 所有
then
回调都是异步执行的。
这些确实解决了当前jQueryDeferred
实现所固有的问题。
我假设 Parse 计划静默迁移此true
设置以成为默认设置,并正在测试它是否会破坏用户的任何内容。我猜即使尚未记录,使用它也很安全。
我想让所有 Parse API 返回我的自定义库的承诺。
这不是那么简单,虽然它可以做到。基本上有两种方法:
- 通过组合它们来装饰 API 中的所有承诺返回方法
Promise.resolve
,这基本上是 @dancamper 建议的
Parse.Promise
用你的库周围的包装器覆盖。
第二种似乎更高效、更稳定,更易于维护,因为在 Parse 更改其 API 时不需要调整。
Parse.Promise = (function(oldPromise, Promise) {
function promise() {
var res, rej;
var p = new Promise(function(_res, _rej) {
res = _res;
rej = _rej;
});
p.resolve = res;
p.reject = rej;
return p;
}
promise.is = oldPromise.is;
promise.as = Promise.resolve;
promise.error = Promise.reject;
promise.when = Promise.all; // ²
promise._continueWhile = oldPromise._continueWhile;
Promise.prototype._continueWith = oldPromise.prototype._continueWith;
Promise.prototype._thenRunCallback = oldPromise.prototype._thenRunCallback;
// you might not need / want these ³
Promise.prototype.always = oldPromise.prototype.always;
Promise.prototype.done = oldPromise.prototype.done;
Promise.prototype.fail = oldPromise.prototype.fail;
return promise;
}(Parse.Promise, require("Bluebird"))); // or whatever
2:Promise.all
解析为数组,同时Parse.Promise.when
使用多个参数解析(见下文)。您可能希望/需要保留它并promise.when = oldPromise.when;
改为使用。
3:确保不要在此处覆盖自定义库的方法。Parse 不需要这些方法,它们是为了与 jQuery 兼容。
请注意,Parse 确实像 jQuery 一样,有时会使用多个值解析它的 Promise,例如在Parse._ajax
. 它在内部不依赖此功能,但您应该检查您最喜欢的 Promise 库如何处理它们。