【问题标题】:how to get the result from recursive promises in a redux action如何从 redux 操作中的递归承诺中获取结果
【发布时间】:2019-11-22 01:43:32
【问题描述】:

我已经搜索了网络,但我找不到解决方案。我的最终目标是从 dynamodb 表中提取所有数据。问题是当一个表大于 1MB 时,在响应中我会得到一个数据块和一个 LastEvaluatedKey 参数(它提供了我可以在下一次调用中使用的索引来获取下一个块)。 scan 操作记录在 here 如果需要。

我在我的应用中使用 reactjs、redux 和 redux-thunk。

我在单一或链式格式中适度使用了 Promise,但这个更具挑战性,到目前为止我可以解决。令我困惑的是,如果没有收到先前的响应,就无法拨打新电话,因此我认为这些电话不能同时进行。另一方面,由于scan 操作是一个承诺(据我所知),如果我尝试从我自己的方法返回一个承诺,则该操作不会收到结果。

我很困惑,我真的很想了解如何让它发挥作用。

行动:

function getDynamodbTableRecords(tableName) {
    return dispatch => {
        dispatch(request());

        var recordsSet = [];
        var data = myAwsService.getTableRecords(tableName, null) || {Items:[]};
        if (data.Items.length > 0){
            data.Items.map(record => {
                recordsSet.push(record);
            });

            dispatch(success(recordsSet));
        } else {
            dispatch(failure("No Records Found!"));
        }
    };

    function request() { return { type: DATA_LOADING, selectedTable: tableName } }
    function success(tableRecords) { return { type: DATA_LOAD_SUCCESS, tableRecords } }
    function failure(error) { return { type: DATA_LOAD_FAILED, errors: error } }
}

myAwsService:

function getTableRecords(tableName, lastEvaluatedKey = null) {
    getRecordsBatch(tableName, lastEvaluatedKey)
    .then(
        data => {
            if (data.LastEvaluatedKey) {
                return getTableRecords(tableName, data.LastEvaluatedKey)
                .then(
                    nextData => {
                        data.Items = data.Items.concat(nextData.Items);
                    }
                )
            }

            return data;
        }
    )
}

function getRecordsBatch(tableName, lastEvaluatedKey = null) {
    var awsDynamodb = new DynamoDB();

    let params = { TableName: tableName };
    if (lastEvaluatedKey) {
        params['ExclusiveStartKey'] = lastEvaluatedKey;
    }

    return new Promise((resolve, reject) => {
        awsDynamodb.scan(params, function(err, data) {
            if (err) {
                reject(err);
            }

            return resolve(data);
        });
    });
}

【问题讨论】:

    标签: reactjs redux promise aws-sdk


    【解决方案1】:

    不确定您的递归承诺是否有效,但我会这样做:

    function getTableRecords(
      tableName,
      lastEvaluatedKey = null,
      result = { Items: [] }
    ) {
      return getRecordsBatch(tableName, lastEvaluatedKey).then(
        data => {
          if (data.LastEvaluatedKey) {
            return getTableRecords(
              tableName,
              data.LastEvaluatedKey,
              {
                ...data,
                Items: result.Items.concat(data.Items),
              }
            );
          }
    
          return {
            ...data,
            Items: result.Items.concat(data.Items),
          };
        }
      );
    }
    

    动作还应该调度 data.Items 而不是 getTabelRecords 返回的承诺,如果出现问题,您可能希望调度失败动作:

    function getDynamodbTableRecords(tableName) {
      return async dispatch => {
        dispatch(request());
    
        //you probably want the data, not a promise of data
        try {
          var data = await myAwsService.getTableRecords(
            tableName,
            null
          );
          if (data.Items.length > 0) {
            //no reason to have the temporary recordSet variable
            dispatch(success(data.Items.map(record => record)));
          } else {
            dispatch(failure('No Records Found!'));
          }
        } catch (e) {
          dispatch(failure(e.message));
        }
      };
    
      function request() {
        return { type: DATA_LOADING, selectedTable: tableName };
      }
      function success(tableRecords) {
        return { type: DATA_LOAD_SUCCESS, tableRecords };
      }
      function failure(error) {
        return { type: DATA_LOAD_FAILED, errors: error };
      }
    }
    

    【讨论】:

    • 很抱歉耽搁了。我正在尝试修复控制台中显示的错误。 Uncaught ReferenceError: regeneratorRuntime is not defined 发生在异步位置。我会看看我能不能尽快解决这个问题,看看代码是否有效
    • 感谢您,并对这里的巨大延迟表示歉意。它终于奏效了!谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 2018-12-22
    • 2017-10-18
    • 2017-08-04
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 2020-04-06
    • 2014-02-04
    相关资源
    最近更新 更多