使用lodash,点击()的链首先执行

问题描述:

我试图使用lodash链来同步执行动作,但它似乎.tap()首先执行,我找不到一个正确的方法来做到这一点使用诺言。我虽然链lodash允许行动,以在同步的方式跟随,是指自来水不会执行,直到结束的forEach使用lodash,点击()的链首先执行

const ids = [ 
 
     { 
 
     "id": 1, 
 
     "refs": [ 
 
      { 
 
       "skuId": 693194, 
 
       "sizeId": "12M", 
 
       "colorId": "ROSE" 
 
      }, 
 
      { 
 
       "skuId": 693195, 
 
       "sizeId": "14M", 
 
       "colorId": "ROSE" 
 
      }, 
 
      { 
 
       "skuId": 973804, 
 
       "sizeId": "6M", 
 
       "colorId": "GREEN" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     "id": 2, 
 
     "refs": [ 
 
      { 
 
       "skuId": 693174, 
 
       "sizeId": "13M", 
 
       "colorId": "RED" 
 
      }, 
 
      { 
 
       "skuId": 693995, 
 
       "sizeId": "14M", 
 
       "colorId": "BLUS" 
 
      } 
 
     ] 
 
     } 
 
    ] 
 
     
 
    let id = 1 
 
     
 
    _(ids) 
 
    .chain() 
 
    .map(value => { 
 
     id = _.result(_.find(value.refs, function(sku) { 
 
        return sku.colorId === 'ROSE' && 
 
        sku.sizeId === '14M'; 
 
            }), 'skuId'); 
 
            
 
    }) 
 
    .tap(() => console.log('id: ', id)) 
 
    .value()
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

+1

没有什么异步这段代码?你为什么提到承诺? – nem035

+0

@ nem035你是什么意思,我的意思是使用诺而不是链 – kyserslick

+0

我不确定你的问题是什么。你是说“tap”是先执行,你想知道为什么?或者你想重构这段代码来使用承诺? –

您正确使用chain我不认为 - check out the docs,你有通过调用.value()来打开该值,如文档示例中所示。 Tap实际上并不是先执行。

let id = null; 

_.chain(ids) 
    .forEach(value => { 
    id = _.result(_.find(value.refs, function(sku) { 
     return sku.colorId === 'ROSE' 
     && sku.sizeId === '14M'; 
     }), 'skuId');          
    }) 
    .tap(() => console.log(id)) 
    .value(); 

我不是100%肯定你正在尝试做的,但我把它改写使用地图摆脱外ID:

const ids = [ 
 
    { 
 
    "id": 1, 
 
    "refs": [ 
 
     { 
 
      "skuId": 693194, 
 
      "sizeId": "12M", 
 
      "colorId": "ROSE" 
 
     }, 
 
     { 
 
      "skuId": 693195, 
 
      "sizeId": "14M", 
 
      "colorId": "ROSE" 
 
     }, 
 
     { 
 
      "skuId": 973804, 
 
      "sizeId": "6M", 
 
      "colorId": "GREEN" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    "id": 2, 
 
    "refs": [ 
 
     { 
 
      "skuId": 693174, 
 
      "sizeId": "13M", 
 
      "colorId": "RED" 
 
     }, 
 
     { 
 
      "skuId": 693995, 
 
      "sizeId": "14M", 
 
      "colorId": "BLUS" 
 
     } 
 
    ] 
 
    } 
 
] 
 

 
let val = _.chain(ids) 
 
    .map(value => { 
 
    return _.result(
 
     _.find(
 
     value.refs, 
 
     sku => sku.colorId === 'ROSE' && sku.sizeId === '14M' 
 
    ), 
 
     'skuId'); 
 
    }) 
 
    .value(); 
 

 
console.log(val);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

你仍然可能需要调整你的代码以获得你所期望的。

+0

我更新了我的代码,实际上我正在尝试分配ID,因为我在抽头内部做了更多的事情 – kyserslick

+0

@kyserslick更新您的问题以完全解释您在内部点击时想要做的事情。很可能你所做的是错误的,因为*id只是分配给它的最后一个id。如果您正在尝试合并ID,“减少”可能就是您想要的。 另外,你有'undefined'作为输出的原因是数组中的第二项没有匹配具有ROSE和14M大小的ref。 –

+0

@kyserslick我刚刚更新了我的代码,以打印出具有匹配skuID的结果数组。第一个项目有匹配,第二个项目没有(因此它是未定义的)。在调用函数'value'后,lodash评估你的链('chain'启动一个懒惰的评估表达式),并返回一个普通的值(在这个例子中是一个数组)。 –

如果添加一行转储idmap的价值,你会发现id设置两次,第二次是null其覆盖你想要的值。

const ids = [ 
 
     { 
 
     "id": 1, 
 
     "refs": [ 
 
      { 
 
       "skuId": 693194, 
 
       "sizeId": "12M", 
 
       "colorId": "ROSE" 
 
      }, 
 
      { 
 
       "skuId": 693195, 
 
       "sizeId": "14M", 
 
       "colorId": "ROSE" 
 
      }, 
 
      { 
 
       "skuId": 973804, 
 
       "sizeId": "6M", 
 
       "colorId": "GREEN" 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     "id": 2, 
 
     "refs": [ 
 
      { 
 
       "skuId": 693174, 
 
       "sizeId": "13M", 
 
       "colorId": "RED" 
 
      }, 
 
      { 
 
       "skuId": 693995, 
 
       "sizeId": "14M", 
 
       "colorId": "BLUS" 
 
      } 
 
     ] 
 
     } 
 
    ] 
 
     
 
    let id = 1 
 
     
 
    _(ids) 
 
    .chain() 
 
    .map(value => { 
 
     id = _.result(_.find(value.refs, function(sku) { 
 
        return sku.colorId === 'ROSE' && 
 
        sku.sizeId === '14M'; 
 
            }), 'skuId'); 
 
     // Add this line to inspect the id value in map 
 
     console.log('id (in map): ', id); 
 
    }) 
 
    .tap(() => console.log('id: ', id)) 
 
    .value()
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>