使用Promise来创建“;原子“;Javascript中的代码块
Using a Promise to create "atomic" blocks of code in Javascript
我来自Java背景,现在正试图将我的思想集中在Javascript的异步特性上。我在代码中使用Promise来实现这一点,直到现在,一切都像一种魅力,但现在我有一个概念性的问题,即使在多次阅读Promise/a+规范后也没有找到明确的答案。
我的要求是:我有一个方法可以修改共享对象,将更新存储在PouchDB中,然后再读取它,以便从数据库中获得更新的修订id字段(乐观锁定)。在Pouch中存储和更新数据是异步的(为了简洁起见,我省略了存储"this"来调用promise中的方法):
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)如果有可能,以下解决方案是故障安全的(它在我的测试中有效,但由于我不知道我的测试是否考虑了所有可能性…;再次省略了存储"this"):
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);
});
});
}
我认为如果实现一个promise(调用done())将同步调用下一个then()函数,它应该可以正常工作,但我无法找到是否是这种情况的确切答案。
如有任何澄清,我们将不胜感激,并感谢您的帮助。
正如您在这里尝试做的那样,Chaining promise确实如预期的那样工作,但我不认为有任何保证done
被同步调用。我认为您的代码可以工作,但其中有一些反模式。我建议简化以避免显式创建promise。
还要考虑:如果您连续调用setValue
4次,那么应该往返服务器多少次?这样做会花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;
});
});
}
- 云代码(javascript)失败,原因是:{代码:1,消息:内部错误
- 简化此If语句,使其不会't重复代码-Javascript
- 十进制到二进制代码Javascript
- 第二次单击时执行不同的代码(JavaScript)
- 在不使用jquery($symbol)knockout.js的情况下分离代码javascript
- 缩短几个元素的onclick代码 - JavaScript
- 英国银行排序代码 JavaScript 正则表达式
- 我无法在谷歌图表的代码 javascript 中获取 json 数据(项目 Python Hello Dashboard
- 和代码 JavaScript 没有被 &.
- 我怎样才能减少这段代码 javascript 代码,这样它就不会那么重复了
- 我想单击一个按钮,一次只执行已经制作的程序中的一行代码.(JavaScript)
- 滑动 DIV 代码 Javascript 的小问题
- 尝试重写代码 JavaScript
- 是否可以检测到在不使用键代码 javascript 的情况下按下了输入键
- 输入网址代码 JavaScript 播放器
- 管理通用客户端代码(javascript/css)
- 理解代码javascript
- 加载json-url参数代码(javascript修改)
- 变量检查错误的代码(javascript)
- css属性仅由代码javascript应用