我有两种文档类型,清单和产品。一上市对象包含了某些国家的产品列表,像这样:在存储过程中获取多个文档(Azure DocumentDB)
上市:
{
"Name": "Default",
"Countries": {
"_default": [
"4QlxAPFcCAAPAAAAAAAAAA==",
"4QlxAPFcCAAHAAAAAAAAAA=="
],
"US": [
"4QlxAPFcCAAIAAAAAAAAAA==",
"4QlxAPFcCAAHAAAAAAAAAA=="
]
},
"Type": "Listing",
"id": "dfed1839-07c5-482b-81c5-669b1dbcd0b6",
"_rid": "4QlxAPFcCAAEAAAAAAAAAA=="
}
产品:
{
"Name": "Widget",
"Price": 3.45,
"Type": "Product",
"_rid": "4QlxAPFcCAAHAAAAAAAAAA=="
}
我的目标是创建一个存储过程Azure DocumentDB集合中的采用两个参数rid
和country
,它们基本上会以最有效的方式获取上市文件和该国的文件。我的推测是,使用getContext().getCollection().readDocument(...)
通过其资源ID加载文档将是最快的方式,因此试图为此创建存储过程。
我的尝试是使用带有yield的发生器/迭代器,然后用纯粹的方法嵌套连续调用(callback hell?)。所有的尝试都给出了相同的结果:
它将获取第一个文档,但会在收到文档后非常突然地结束。
供参考,这是我的最新尝试:
function test(rid, country) {
var collection = getContext().getCollection();
var collectionSelfLink = collection.getSelfLink();
var docsLink = collectionSelfLink + "docs/";
var body = getContext().getResponse().setBody;
function getDocument(rid) {
return new Promise(function(resolve, reject) {
var accepted = collection.readDocument(docsLink + rid, (err, doc, opts) => {
resolve(doc);
});
if (!accepted)
reject("Not accepted");
});
}
getDocument(rid)
.then(doc => {
body("0. First step"); // set test body
// Countries is a Dictionary<string, string[]> with resource ids
return doc.Countries[country] || doc.Countries["_default"];
})
// This is how far it gets, resulting in response "1. Documents to fetch: 2"
.then(a => body("1. Documents to fetch: " + a.length))
.then(a => a.map(function(productId) { return getDoument(productId); }))
.then(a => body("2. It should come this far, right?"))
.then(a => Promise.all(a))
.then(a => body(a))
.catch(function(e) { throw new Error(JSON.stringify(e)); });
}
我不是承诺专家。我倾向于手动编写我的回调代码或使用async.js(是的,你可以将它作为一个存储在sproc中的依赖项加载),但我想知道你的问题是否在调用'a.map'的行中。包裹'.then'将返回一个承诺,这是从这一点开始的一系列承诺。你也可以在你的'.then()'调用中使用单行函数,但其中的一些内容(调用body,甚至调用.map可以按照顺序完成)。唯一你需要的是一个promise因为是异步调用readDocument。另一方面,这可能只是一种承诺编码风格。 –
我在一个带有模拟'getDocument'函数的REPL中尝试了上述调用链,并且它工作正常。试图做for循环内的初始'collection.readDocument(...)',并使用当换的/用于费/因为它会中途通终止(服用2选自4种元素的我曾在list)当使用'.forEach'时,它会遍历整个数组,但不会等到这些调用完成后,我很好奇调用者如何确定何时“终止”... –
有多大数组?如何扇出('a.map()')承诺链决定多少并行化imp字元素?我的新理论是用for循环或者你的a.map承诺方法,你的范围太广泛了,超过了一些资源。您可能需要像async.js''... Limit()'方法那样限制并行化。 –