我想知道如何在Q promises中完成“链接链接”之间的共享价值,而不会完全贬低承诺的相当成语。
我正在使用Q在mongo数据库上做一些逻辑。我的GET
端点逻辑看起来很棒:
return Q.ninvoke(this.db, 'collection', 'namespace')
.then(function(namespaceCollection){
return Q.ninvoke(namespaceCollection,'findOne',{"name":name})
}).then(function(queryResults){
if(!queryResults){
throw new providerErrors.NotFound();
return
}
return queryResults;
},function(err){
throw new providerErrors.BadRequest();
});;
然后将相同的模式应用于我的插入端点,我遇到了一个问题。我必须使用从第一个promise返回的集合,即从db对象获取集合的集合,以便将值保存回来:
return Q.ninvoke(this.db,'collection','namespace')
.then(function(namespaceCollection){
return Q.ninvoke(namespaceCollection,findOne,{"name":namespace.name});
})
.then(function(foundNamespace){
if(namespace){
throw new providerErrors.Conflict();
return
}
//This is a new namespace object, give it a datetime and then
//let's save it!
namespace.createDate = new Date();
})
.then(function(namespaceToSave){
//uhoh! no collection in scope down here, just the value to persist!
})
我想知道解决这个问题的最佳,最惯用的方法是什么。我探讨Q.all
作为一种可能的解决方案,但这显然无法确保事件的顺序。
答案 0 :(得分:1)
一旦清理了变量命名,就可以在第一个Q.ninvoke之前在范围内声明一些东西。在第一个回调中,将其分配给CB值,然后在第三个命名空间中使用它。
var namespaceCollection = null;
return Q.ninvoke(this.db,'collection','namespace')
.then(function(namespaceCol){
namespaceCollection = namespaceCol;
return Q.ninvoke(namespaceCollection,findOne,{"name": namespace.name});
})
.then(function(foundNamespace){
if(!foundNamespace){
throw new providerErrors.Conflict();
return
}
//This is a new namespace object, give it a datetime and then
//let's save it!
namespace.createDate = new Date();
})
.then(function(namespaceToSave){
// namespaceCollection is now available!
})
答案 1 :(得分:1)
最适合捕获闭包中后续步骤所需的值。 Promise可以嵌入处理程序中。顺序性由then
保留,即使在嵌套链中也存在,通过从处理程序返回一个promise。
return Q.ninvoke(this.db,'collection','namespace')
.then(function(namespaceCollection){
return Q.ninvoke(namespaceCollection,'findOne',{"name":namespace.name});
.then(function(foundNamespace){
return // presumably returning a promise for the namespace
// to save here, otherwise, `then` chaining is unnecessary
})
.then(function(namespaceToSave){
// namespaceCollection is in scope
})
})