节点异步映射在redux动作中未正确执行

时间:2018-07-11 15:41:53

标签: reactjs async-await node-async

我连接到以以下格式返回数据的API:

[
    {
        "id": 23,
        "name": "11:40AM July 2",
        "airplayEnabled": false,
        "airplayCodeEnabled": true,
        "type": 0,
        "groups": [
            {
                "id": 4,
                "name": "Hallway",
                "notes": "Any devices present in the hallway",
                "_pivot_device_id": 23,
                "_pivot_group_id": 4
            },
            {
                "id": 5,
                "name": "Middle school",
                "notes": "In classrooms 6-8",
                "_pivot_device_id": 23,
                "_pivot_group_id": 5
            }
        ],
        "mac": "123456789ABC"
    },
    {
        "id": 26,
        "name": "1:54PM July 5",
        "airplayEnabled": false,
        "airplayCodeEnabled": true,
        "type": 0,
        "groups": [
            {
                "id": 5,
                "name": "Middle school",
                "notes": "In classrooms 6-8",
                "_pivot_device_id": 26,
                "_pivot_group_id": 5
            }
        ],
        "mac": "123456789ABC"
    }
]

我想修改每个退回的商品并删除多余的数据,所以最终会像这样:

[
    {
        "id": 23,
        "name": "11:40AM July 2",
        "airplayEnabled": false,
        "airplayCodeEnabled": true,
        "type": 0,
        "groups": [4, 5],
        "mac": "123456789ABC"
    },
    {
        "id": 26,
        "name": "1:54PM July 5",
        "airplayEnabled": false,
        "airplayCodeEnabled": true,
        "type": 0,
        "groups": [5],
        "mac": "123456789ABC"
    }
]

我创建了以下代码以删除多余的数据:

const deleteExcessInfo = async function(group) {
  if(group.id) {
    return group.id;
  } else {
    return null;
  }
}

const modGroups = async function(device) {
  async.map(device.groups, deleteExcessInfo, function(err, res) {
    device.groups = res;
  });
  return device;
}

var newDevices;

async.map(devices, modGroups, (error, results) => {
  console.log("results are " + JSON.stringify(results));
});

当我在独立的节点程序(从命令行运行)中执行此代码时,我得到了预期的输出,并删除了多余的数据。但是,当我将它放在redux动作中时,它是行不通的,

export function getDevices() {
  return function(dispatch) {
    return fetch("http://my-awesome-api:1357/device", {mode: "cors"})
    .then(handleErrors)
    .then(json)
    .then(function(data) {
      async.map(data, fixGroups, async function(error, res) {
        console.log("dispatching...");
        console.log(JSON.stringify(res));
        dispatch({
          type: "GET_DEVICES",
          devices: res
        });
      });
    }).catch((err) => {
      dispatch({
        type: "GET_DEVICES_ERROR",
        error: err
      });
      alert("Oh shoot we have an error " + err);
      return(err);
    });
  }
};

我看不到控制台上显示的“ dispatching ...”或res,因此似乎由于某种原因未执行回调函数。关于它为什么不起作用以及如何修复的任何想法?谢谢!

我尝试过的

我尝试按照Moonjsit的建议执行诺言,但没有成功。我也尝试过在Redux动作中实现诺言,如下所示:

export function getDevices() {
  return function(dispatch) {
    return fetch("http://localhost:1357/device", {mode: "cors"})
    .then(handleErrors)
    .then(json)
    .then(function(data) {
      return new Promise((resolve, reject) => {
        async.map(data, fixGroups, (error, results) => {
          console.log("results are " + JSON.stringify(results));
          resolve(dispatch({
            type: "GET_DEVICES",
            devices: results
          });
        });
      });
    }).catch((err) => {
      dispatch({
        type: "GET_DEVICES_ERROR",
        error: err
      });
      alert("Oh shoot we have an error " + err);
      return(err);
    });
  }
};

无论哪种方式,回调中的代码都不会执行。

1 个答案:

答案 0 :(得分:0)

嘿,所以您的代码有问题。

const modGroups = async function(device) {
  async.map(device.groups, deleteExcessInfo, function(err, res) {
    device.groups = res;
  });
  return device;
}

上面的调用函数立即启动异步的async.map,然后返回未更改的device变量。如此有效地得出与以下结果相同的结果:

const modGroups = async function(device) {
  return device;
}

要修复它,您可以例如。将其包装在Promise中:

const modGroups = async function(device) {
  return new Promise((resolve, reject) => {
    async.map(device.groups, deleteExcessInfo, function(err, res) {
      if (err) {
        reject(err);
      } else {
        device.groups = res;
        resolve(device);
    });
  })
}