我有兩種文檔類型,清單和產品。一上市對象包含了某些國家的產品列表,像這樣:在存儲過程中獲取多個文檔(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()'方法那樣限制並行化。 –