Javascript 使用Q.Promises递归地从DynamoDB获取记录

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',

我在使用递归dynamodb调用实现Q承诺时遇到了问题,这是nodejs和Q的新功能,考虑到dynamodb检索结果的局限性,我们需要运行递归查询来获得所需的结果

通常情况下,我们将查询与Q实现一起使用,如下所示

    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不在范围内,我贴了一些问题,这就是为什么在递归调用时要解决这个问题谢谢,对于解决方案,我已经找到了一个解决方案,但是你的解决方案也很有效:),所以我接受它