我担心 Parse 使用与 jQuery 兼容的 Promise,因为我读过 jQuery Promise 允许消费者改变 Promise 的状态。
您无需担心。 “jQuery 兼容”可能意味着很多事情,Parse 承诺当然不允许消费者改变他们的状态1(因为 jQuery 多年来也没有这样做)。顺便说一句,它们也是 A+ “兼容” :-)
1:通过公共方法。因此,不会比大多数其他实现更多。
是否可以使用已知与 Parse JavaScript SDK 兼容的另一个 Promises/A+ 的 Promise 实现?
是的。 Parse SDK 确实返回有效的 A+ thenables,这意味着您可以从您最喜欢的 Promise 实现的 then 回调中返回 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() 方法。详情见issue #57。
我查看了the code,这个标志基本上改变了 3 件事:
-
then 回调中的异常被捕获并导致结果承诺被拒绝,而不是全局错误。所以你可以在其中使用throw。
- 如果您
return 来自 onRejected 回调(then 的第二个参数)的值,则应该处理错误并且结果承诺会被履行而不是被拒绝。
- 所有
then 回调都是异步执行的。
这些确实解决了当前时间的problems inherent to the jQuery Deferred implementation。
我假设 Parse 计划静默迁移此 true 设置以成为默认设置,并正在测试它是否会破坏用户的任何内容。我猜它是相当安全的,即使还没有记录。
我想让所有 Parse API 返回我的自定义库的承诺。
这不是那么简单,虽然它可以做到。基本上有两种方法:
- 通过使用
Promise.resolve 组合来装饰API 中的所有返回承诺的方法,这基本上是@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 库如何处理它们。