Javascript 使用Q.Promises递归地从DynamoDB获取记录
我在使用递归dynamodb调用实现Q承诺时遇到了问题,这是nodejs和Q的新功能,考虑到dynamodb检索结果的局限性,我们需要运行递归查询来获得所需的结果 通常情况下,我们将查询与Q实现一起使用,如下所示Javascript 使用Q.Promises递归地从DynamoDB获取记录,javascript,node.js,amazon-dynamodb,q,Javascript,Node.js,Amazon Dynamodb,Q,我在使用递归dynamodb调用实现Q承诺时遇到了问题,这是nodejs和Q的新功能,考虑到dynamodb检索结果的局限性,我们需要运行递归查询来获得所需的结果 通常情况下,我们将查询与Q实现一起使用,如下所示 function getDBResults(){ var q = Q.defer(); var params = { TableName: mytable, IndexName: 'mytable-index',
function getDBResults(){
var q = Q.defer();
var params = {
TableName: mytable,
IndexName: 'mytable-index',
KeyConditionExpression: 'id = :id',
FilterExpression: 'deliveryTime between :startTime and :endTime',
ExpressionAttributeValues: {
':startTime': {
N: startTime.toString()
},
":endTime": {
N: endTime.toString()
},
":id": {
S: id.toString()
}
},
Select: 'ALL_ATTRIBUTES',
ScanIndexForward: false,
};
dynamodb.query(params, function(err, data) {
if (err) {
console.log('Dynamo fail ' + err);
q.reject(err);
} else {
console.log('DATA'+ data);
var results = data.Items;
q.resolve(results);
}
});
return q.promise;
}
getDBResults.then(
function(data) {
// handle data
},
function(err) {
//handle error
}
);
使用递归查询,我可以得到结果,但我需要在另一个函数中使用这些结果,但由于nodejs的异步性质,下一个函数调用已经在递归查询函数完成其工作之前发生,现在我想从递归查询函数中获得所有结果,然后作为对新函数的承诺获得结果,并最终处理所有数据
dynamodb的递归查询如下所示
function getDBResults(){
//var q = Q.defer();
params = {
TableName: mytable,
IndexName: 'mytable-index',
KeyConditionExpression: 'id = :id',
FilterExpression: 'deliveryTime between :startTime and :endTime',
ExpressionAttributeValues: {
':startTime': {
N: startTime.toString()
},
":endTime": {
N: endTime.toString()
},
":id": {
S: id.toString()
}
},
Select: 'ALL_ATTRIBUTES',
ScanIndexForward: false,
};
dynamodb.query(params, onQueryCallBack);
}
function onQueryCallBack(err, data) {
if (err) {
console.log('Dynamo fail ' + err);
console.error("Could not query db" + err);
} else {
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("query for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
dynamodb.query(params, onQueryCallBack);
}
data.Items.forEach(function(item) {
allResults.push(item);
});
//console.log('NO:OF Results:' + allResults.length);
//q.resolve(tickets);
//});
getDBResults.then(
function(data) {
// handle data
},
function(err) {
//handle error
}
);
}
现在我希望我能最终得到结果,这样我就能在下一个函数中处理它们
function getDBResults(){
//var q = Q.defer();
params = {
TableName: mytable,
IndexName: 'mytable-index',
KeyConditionExpression: 'id = :id',
FilterExpression: 'deliveryTime between :startTime and :endTime',
ExpressionAttributeValues: {
':startTime': {
N: startTime.toString()
},
":endTime": {
N: endTime.toString()
},
":id": {
S: id.toString()
}
},
Select: 'ALL_ATTRIBUTES',
ScanIndexForward: false,
};
dynamodb.query(params, onQueryCallBack);
}
function onQueryCallBack(err, data) {
if (err) {
console.log('Dynamo fail ' + err);
console.error("Could not query db" + err);
} else {
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("query for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
dynamodb.query(params, onQueryCallBack);
}
data.Items.forEach(function(item) {
allResults.push(item);
});
//console.log('NO:OF Results:' + allResults.length);
//q.resolve(tickets);
//});
getDBResults.then(
function(data) {
// handle data
},
function(err) {
//handle error
}
);
请在这方面帮助我,如果这是一个愚蠢的问题,很抱歉,但是带有承诺的递归调用给我造成了障碍
谢谢首先,保留您已有的预期功能。使用它作为递归解决方案的构建块,而不是试图改变它 不过,它可能需要两个小的调整:
function getDBResults(startKey){
// ^^^^^^^^
var q = Q.defer();
var params = {
ExclusiveStartKey: startKey,
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
… // rest as before
};
dynamodb.query(params, function(err, data) {
if (err) {
q.reject(err);
} else {
q.resolve(data);
// ^^^^ Not `data.Items`
}
});
return q.promise;
}
现在我们可以用它来实现递归解决方案:
function getRecursiveDBResults(key) {
return getDBResults(key).then(function(data) {
if (typeof data.LastEvaluatedKey != "undefined") {
return getRecursiveDBResults(data.LastEvaluatedKey).then(items) {
return data.Items.concat(items);
});
} else {
return data.Items
}
});
}
下面是我解决问题的方法,也感谢Bergi提供的解决方案
function getDBResults() {
var q = Q.defer();
var dynamodb = core.getDynamoDB();
params = {
TableName: mytable,
IndexName: 'mytable-index',
KeyConditionExpression: 'id = :id',
FilterExpression: 'deliveryTime between :startTime and :endTime',
ExpressionAttributeValues: {
':startTime': {
N: startTime.toString()
},
":endTime": {
N: endTime.toString()
},
":id": {
S: id.toString()
}
},
Select: 'ALL_ATTRIBUTES',
ScanIndexForward: false,
};
var results = [];
var callback = function(err, data) {
if (err) {
console.log('Dynamo fail ' + err);
q.reject(err);
} else if (data.LastEvaluatedKey) {
params.ExclusiveStartKey = data.LastEvaluatedKey;
dynamodb.query(params, callback);
} else {
q.resolve(results);
}
data.Items.forEach(function(item) {
results.push(item);
});
}
dynamodb.query(params, callback);
return q.promise;
}
当
onQueryCallBack
不在范围内时,如何解决q
问题以查看延迟?其可能重复的不重复Bergi,问题不是将回调API转换为承诺,而是将其更多地转换为递归回调到承诺,是的,onQueryCallBack不在范围内,我贴了一些问题,这就是为什么在递归调用时要解决这个问题谢谢,对于解决方案,我已经找到了一个解决方案,但是你的解决方案也很有效:),所以我接受它