【问题标题】:How to setState only when "map" loop is finished?仅当“地图”循环完成时如何设置状态?
【发布时间】:2018-02-04 14:24:37
【问题描述】:

我发送了一些 http 请求,在 Promise 解决之后,我需要遍历数组并执行一些异步操作。我想使函数保持异步,但我只需要在“map”循环完成后执行 setState:

fetchData = () => {
 let data = [];
 let tickets  = http.get('/api/zendesk/tickets'),
     users    = http.get('/api/zendesk/users'),
     items    = http.get('/api/orders/items'),
     reqTypes = http.get("/api/support/requests");

 Promise.all([users,tickets,items,reqTypes])
  .then(values => {
    console.log(values);
    let usersArr = values[0].data.users,
      ticketsArr = values[1].data.tickets,
        itemsArr = values[2].data,
      requestArr = values[3].data;

    data = ticketsArr.map((ticket,key) => {

      let id = ticket.custom_fields.find(field => field.id === productions_fields.order_id || field.id === develop_fields.order_id).value;

      id === null ? ticket.Items = [] : ticket.Items = itemsArr.filter(item => item.order_id === parseInt(id));

      ticket.Requests = requestArr.filter(request => request.id === ticket.id);
    })

    this.setState({tickets:data})

  }).catch(err => console.log(err))
 }

是否可以做或者我需要像“for”一样制作同步循环?

【问题讨论】:

  • 当前代码有什么问题?也在地图里面哪个动作是异步的?
  • 当我打印状态时得到一个“未定义对象”数组...我认为“过滤器”方法是异步的,不是吗?

标签: javascript reactjs asynchronous promise setstate


【解决方案1】:

我得到一个“未定义对象”数组,为什么?

因为您没有返回地图正文中的任何内容,默认情况下它返回undefined

检查这个sn-p:

let a = [1,2,3,4].map(el => {
   console.log('el = ', el);
})

console.log('a = ', a);   //array of undefined values

如果要修改现有数组,请使用forEach 而不是map

像这样:

ticketsArr.forEach((ticket,key) => {
    let id = ticket.custom_fields.find(field => field.id === productions_fields.order_id || field.id === develop_fields.order_id).value;
    ticket.Items = (id === null) ? [] : itemsArr.filter(item => item.order_id === parseInt(id));
    ticket.Requests = requestArr.filter(request => request.id === ticket.id);
})

this.setState({ tickets: ticketsArr })

【讨论】:

  • 使用forEach检查解决方案,修改现有数组我们应该使用forEach而不是map:)
  • 很高兴它帮助了你:)
【解决方案2】:

Array.prototype.map 期望您返回每个元素的最终形式。现在你没有返回任何东西,因此每个元素都变成了undefined

data = ticketsArr.map((ticket,key) => {
  let id = ticket.custom_fields.find(field => field.id === productions_fields.order_id || field.id === develop_fields.order_id).value;
  id === null ? ticket.Items = [] : ticket.Items = itemsArr.filter(item => item.order_id === parseInt(id));
  ticket.Requests = requestArr.filter(request => request.id === ticket.id);
  return ticket // <- this
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-18
    • 2019-10-05
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2017-07-20
    相关资源
    最近更新 更多