动态创建的数组长度显示为零

时间:2019-04-06 14:34:45

标签: jquery json

我知道这个问题被问了几次,但是大多数答案都是纯JavaScript。

我有一个函数,可以使用产品数据创建一个数组。该数组在其他函数中用于通过JSON获取新数据。

$(function(){
  var product_info = []
  $('.prod').each(function(){
    product_info.push({ 
      id: $(this).data('pid'), amt: $(this).data('qty'), vid: $(this).data('vid'), url: 'some-url/'+$(this).data('pid')+'?secret=secret&quantity='+$(this).data('qty')
    })
  });
  getId(product_info)
});

function getId(product){
  var matched_variant = []
  $.each(product, function(index, item) {
    var vid = item['vid']
    $.getJSON(item['url'], function(data){
      $.each(data.variants, function(i, variant){
         if(variant.id == vid){
           matched_variant.push({
                id: variant.id, dt: Number(variant.deliveryTimeInDays), dtt: variant.deliveryTime, co: variant.cutOffTime, sid: variant.supplier_id 
          })
         }
      });
    }); 
  });
  console.log(matched_variant.length, matched_variant)
}

当我执行console.log matched_variant.length时,它始终显示0。但是里面有元素,如下所示(从console.log复制)

[
  {
    "id": 79380296,
    "dt": 3,
    "dtt": "in three days",
    "co": "15:00",
    "sid": 5
  },
  {
    "id": 79380299,
    "dt": 1,
    "dtt": "same day",
    "co": "17:00",
    "sid": 5
  }
] 

为什么长度总是等于零? 我已经读到,这可能与asynchronyous(??)有关。但是那该怎么办呢?创建某种成功功能?

任何帮助都将不胜感激!

已更新数据响应

 {
  "id": 41853029,
  "variants": {
    "79380290": {
      "id": 79380290,
      "supplier_id": 5,
      "on_stock": "no",
      "levelLocal": 0,
      "levelSupplier": 0,
      "deliveryTime": "niet leverbaar",
      "cutOffTime": "15:00",
      "deliveryTimeInDays": -1
    },
    "79380293": {
      "id": 79380293,
      "supplier_id": 5,
      "on_stock": "no",
      "levelLocal": 0,
      "levelSupplier": 0,
      "deliveryTime": "niet leverbaar",
      "cutOffTime": "15:00",
      "deliveryTimeInDays": -1
    },
    "79380296": {
      "id": 79380296,
      "supplier_id": 5,
      "on_stock": "supplier",
      "levelLocal": 1,
      "levelSupplier": 250,
      "deliveryTime": "Voor 15:00 uur besteld, over 3 werkdagen in huis",
      "cutOffTime": "15:00",
      "deliveryTimeInDays": 3
    },
    "79380299": {
      "id": 79380299,
      "supplier_id": 5,
      "on_stock": "supplier",
      "levelLocal": 2,
      "levelSupplier": 250,
      "deliveryTime": "Voor 15:00 uur besteld, over 3 werkdagen in huis",
      "cutOffTime": "15:00",
      "deliveryTimeInDays": 3
    }
  }
}

1 个答案:

答案 0 :(得分:1)

是的。{$.getJSON()是异步的...并且还返回一个Promise

当您需要多个请求来填充一个最终数组时,以一个诺言数组开始,并使用Promise.all()处理所有这些诺言的结果

类似的东西:

// usage
getAllItems().then(function(res){
   // all requests have completed and res is combined results
   console.log(res);
}).catch(function(){
   console.log("One of the requests failed")
});



function getItemData(item) {
  // return single item request promise
  return $.getJSON(item.url).then(function(data) {
    // filter and map the response data required
    return Object.values(data.variants).filter(function(variant) {
      variant.id == item.vid
    }).map(function(variant) {
      return {
        id: variant.id,
        dt: Number(variant.deliveryTimeInDays),
        dtt: variant.deliveryTime,
        co: variant.cutOffTime,
        sid: variant.supplier_id
      }    
    });
  });

}

function getAllItems() {    
  var promiseArray = $('.prod').map(function() {    
    var item = {
      id: $(this).data('pid'),
      amt: $(this).data('qty'),
      vid: $(this).data('vid'),
      url: 'some-url/' + $(this).data('pid') + '?secret=secret&quantity=' + $(this).data('qty')
    };
    // return promise from getItemData()
    return getItemData(item);

  }).get();

  // return promise
  return Promise.all(promiseArray).then(function(res){
     // flatten all the sub arrays produced in getItemData()
     return [].concat.apply([], res)
  })

}