来自Java背景我现在试图围绕Javascript的异步特性。我在我的代码中使用promises来做到这一点,直到现在一切都像一个魅力,但现在我有一个概念性的问题,即使多次阅读Promise / A +规范后也没有找到明确的答案。
我的要求是这样的:我有一个修改共享对象的方法,将更新存储在PouchDB中并随后将其读回,以便从db(乐观锁定)获取更新的修订版ID字段。在Pouch中存储和更新数据是异步的(我省略了存储"这个"为了简洁而在promises中调用方法):
var _doc = ...;
var _pouch = new PouchDB(...);
function setValue(key, value) {
_doc[key] = value;
_pouch.put(_doc)
.then(function() {
return _pouch.get(_doc._id);
})
.then(function(updatedDoc) {
_doc = updatedDoc;
});
}
现在,我想确保在再次读取之前将_doc写入数据库时没有设置其他键。是否(a)甚至可能另一个setValue()调用正在执行put()(具有过时的修订版ID),而来自Pouch的get()调用尚未执行(给定JS正在使用的消息队列方法) )和(b)如果可能的话,以下解决方案是安全的(它在我的测试中工作,但因为我不知道我的测试是否正在考虑所有可能性......;存储"这个"再次被省略):
var _doc = ...;
var _pouch = new PouchDB(...);
var _updatePromise;
function setValue(key, value) {
if (_updatePromise == null) {
setValueInternal(key, value);
}
else {
// make sure the previous setValue() call is executed completely before
// starting another one...
_updatePromise.then(function() {
setValueInternal(key, value);
});
}
}
function setValueInternal(key, value) {
_doc[key] = value;
_updatePromise = new Promise(function(done, reject) {
_pouch.put(_doc)
.then(function() {
return _pouch.get(_doc._id);
})
.then(function(updatedDoc) {
_doc = updatedDoc;
_updatePromise = null;
done();
})
catch(function(error) {
_updatePromise = null;
reject(error);
});
});
}
我认为如果履行承诺(调用done())将同步调用next then()函数它应该正常工作,但是我无法找到明确的答案是否是这种情况。
非常感谢任何澄清,感谢您的帮助。
答案 0 :(得分:1)
你在这里尝试做的链接确实确实按预期工作,但我不相信有done
被同步调用的保证。我认为你的代码可行,但你有一些反模式。我建议简化以避免明确创建承诺。
还要考虑一下:如果你连续4次拨打setValue
,那么到服务器的往返次数应该是多少?这样做会使它成为4.你想将它们分成1或2吗?
setValue
次往返:var _doc = ...;
var _pouch = new PouchDB(...);
var _updatePromise = Promise.resolve();
function setValue(key, value) {
// make sure the previous setValue() call is executed completely before
// starting another one...
_updatePromise = _updatePromise.then(function() {
_doc[key] = value;
return _pouch.put(_doc)
.then(function() {
return _pouch.get(_doc._id);
})
.then(function(updatedDoc) {
_doc = updatedDoc;
});
});
}