[英]Can I make a promise that will only resolve when multiple variables are set?
[英]How can I make a Promise resolve only after recursion is completed?
我在使這種邏輯正常工作時遇到問題,我什至不知道是否有可能或我是否在此處正確使用了Promise。
我有第一個函數,它接收一個ID列表,這些ID用於發出請求以提取特定的異步數據。 我一次只能拉入1000,因此,如果列表包含的數目超過1000,則必須遞歸遍歷。
我正在尋找的是-對於需要遞歸的每個選項,請調用遞歸函數, 等待結果,然后將其推入列表。 獲得所有數據后,請對數據進行響應。
async function getData () {
....
// Inside condition that determines it needs to recurse
let _data = await _getOptions(id, data, 0);
dataList.push(_data);
...
// Eventually, return the data
res.json(dataList);
}
該函數遍歷列表,並且應該在所有數據輸入后解決。
let rData = [];
function _getOptions(id, data, offset) {
return new Promise((resolve, reject) => {
if (data.length < 1000) {
return resolve(rData);
}
let fields = { fields: `id, key_value, label, condition_value`, offset: offset, limit: 1000 };
options.getOptionsWithFilter(id, fields, (err, data) => {
rData.push(data);
_getOptions(id, data, offset + 1000);
});
});
}
似乎由於控制台中拋出錯誤而無法正常工作,這向我暗示它正在返回undefined
。 我想問題是我在這里使用了錯誤的Promise。 但我一直在努力提出另一種解決方案。 我需要繼續在_data
變量中返回所有數據。
您的promise構造函數回調應始終會導致調用resolve
(或reject
),但是當您繼續進行遞歸調用時,就永遠不會在該特定的 promise上調用resolve
。 所以這樣稱呼它:
resolve(_getOptions(id, data, offset + 1000));
我還認為您組合結果數據塊的方式是錯誤的:您會將數組作為嵌套數組推入最終數組。 我希望您需要將這些塊連接成一維數組。
data
變量的使用存在問題:您將它用於傳遞給_getOptions
函數的內容(不確定最初的含義),還用於getOptionsWithFilter
提供的內容 。 我認為后面的數據實際上是您要處理的唯一data
。 因此,您無需將其傳遞給_getOptions
。
最好避免使用全局rData
變量。 由於僅將其設置為空數組一次,因此冒着沒有為要發出的下一個請求清除它的風險。
取而代之的是讓最終的承諾產生最終的數據塊,然后在其之前添加之前的數據塊:
function _getOptions(id, offset = 0) { // No data argument!
return new Promise((resolve, reject) => {
let fields = { fields: `id, key_value, label, condition_value`,
offset: offset, limit: 1000 };
options.getOptionsWithFilter(id, fields, (err, data) => {
if (data.length < 1000) { // Perform the check when you have the data
return resolve(data); // just this chunk
}
resolve(_getOptions(id, offset + 1000) // Don't pass data
// prepend this data to the data that the recursive
// promise will provide
.then(rData => data.concat(rData))
);
});
});
}
您這樣稱呼它:
_data = await _getOptions(id);
您還可以選擇在一個Promise構造函數回調中執行異步循環(“遞歸調用”):
function _getOptions(id) { // No data argument!
return new Promise((resolve, reject) => {
let rData = [];
(function loop(offset) {
let fields = { fields: `id, key_value, label, condition_value`,
offset: offset, limit: 1000 };
options.getOptionsWithFilter(id, fields, (err, data) => {
rData = rData.concat(data);
if (data.length < 1000) { // Perform the check when you have the data
return resolve(rData); // All retrieved data
}
loop(offset + 1000); // Collect more
});
})(0); // Call immediately
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.