Node.js 建议时递归调用DynamoDb扫描

Node.js 建议时递归调用DynamoDb扫描,node.js,aws-lambda,amazon-dynamodb,Node.js,Aws Lambda,Amazon Dynamodb,我需要使用scan()方法从DynamoDb获取一些数据。通过递归调用函数n多次以获得正确的页面,我实现了一些基本分页 目前,我调用了我的函数,在scan()回调函数中,如果数据可以发回,我将使用处理程序回调函数返回数据 现行代码 const AWS = require('aws-sdk') const docClient = new AWS.DynamoDB.DocumentClient() const TABLE_NAME = process.env.TABLE_NAME const DE

我需要使用
scan()
方法从DynamoDb获取一些数据。通过递归调用函数
n
多次以获得正确的
页面,我实现了一些基本分页

目前,我调用了我的函数,在
scan()
回调函数中,如果数据可以发回,我将使用处理程序回调函数返回数据

现行代码

const AWS = require('aws-sdk')

const docClient = new AWS.DynamoDB.DocumentClient()
const TABLE_NAME = process.env.TABLE_NAME
const DEFAULT_PAGE_SIZE = 500
const DEFAULT_PAGE_NUMBER = 1

const self = {
    handler: (event, context, callback) => {
        const {pageNumber, pageSize} = event.queryStringParameters ? event.queryStringParameters : {pageNumber: DEFAULT_PAGE_NUMBER, pageSize: DEFAULT_PAGE_SIZE}

        const params = {
            TableName: ORGANISATION_TYPES_TABLE_NAME,
            Limit: pageSize ? pageSize : DEFAULT_PAGE_SIZE
        }

        return self.scan(params, pageNumber, 1, callback)

    },
    scan: (params, pageNumber, pageCount, callback) => {
        docClient.scan(params, (err, data) => {
            if (err) {
                callback(null, {
                    statusCode: 500,
                    body: JSON.stringify(err)
                })
            };

            if (data.LastEvaluatedKey && pageCount < pageNumber) {
                pageCount += 1
                params.ExclusiveStartKey = data.LastEvaluatedKey
                self.scan(params, pageNumber, pageCount, callback)
            } else {
                callback(null, {
                    statusCode: 200,
                    body: JSON.stringify(data)
                })
            }
            
        })
    }
}

module.exports = self

我还尝试在
docClient.scan()
回调中执行
return-Promise.resolve(data)
,但这也不起作用。就好像承诺无法在回调中得到解决一样?

我最近帮助了一些人解决了这个问题,实际上我们找到了一个非常优雅的解决方案,它在SDK的响应中使用了
hasNextPage
属性。关键是让递归函数通过递归调用传递一个保存结果的数组,然后只需
concat
,直到页面用完,然后返回数组

const scan = async params => {
  function scanRec(promise, xs) {
    return promise
        .then(async result => {
            const response = result.$response;
            const items = xs.concat(result.Items);
            response.hasNextPage() ? scanRec(response.nextPage().promise(), items) : items
        })
}

  return queryAllPagesRec(docClient.query(params).promise(), []);
}
然后以正常方式使用该函数:

const params = { /** params **/ };

scan(params).then(x => {
  // ...
})

对不起,我对承诺和特别是aysnc/aysnc/AYWAIT很陌生。你能解释一下我如何使用上面的代码吗?你实际上不需要
async
位,我只是习惯于让别人知道函数是异步的。我建议您在继续之前先了解承诺和异步/等待是如何工作的。网上有大量的信息,从长远来看,这将使你受益匪浅。我添加了一个关于如何使用该功能的小节。
const params = { /** params **/ };

scan(params).then(x => {
  // ...
})