咖啡脚本承诺递归链问题

Posted

技术标签:

【中文标题】咖啡脚本承诺递归链问题【英文标题】:coffeescript promise recursion chain issue 【发布时间】:2021-11-21 08:28:49 【问题描述】:

我的初始数据是这样的

["id":1,"type":"value","pid":"123",
 "id":2,"type":"value1","pid":"451",
 "id":3,"type":"value3","pid":"132"
]

现在基于type==value1,我将递归调用一个函数,该函数将为该元素pid 提供subset_data 并继续这样。

最终数据会是这样的

[    
    "1":"type":"value","pid":"123", ## transformed id as root key  
    "2":"type":"value1","pid":"451", ## make recursive function call and populate some subset_data for `pid=451`
          "subset_data":[
              "4":"type":"value","pid":"1234",
              "5":"type":"value1","pid":"321",## make recursive function call and populate some subset_data for `pid=321`
                "subset_data":[
                  ...,
                  ...
                 ]
               
              ,
              "6":"type":"value2","pid":"111"
            ]
         
     ,
        
    "3":"type":"value3","pid":"132"
   ]

我已经尝试了几个功能

get_datas = (id) ->
     get_data(id)
        .map (data) ->
            if data.type == "value1"
              get_datas(_.get(data,"pid"))
                .then (subdatas) ->
                  return _.set(
                    ,
                    [data.id, 'subset_data'],
                    subdatas
                  )
            _.zipObject([data.id], [ _.omit(data, 'id')])

这只给出了这个

[  
    "1":"type":"value","pid":"123",
    "2":"type":"value1","pid":"451",
    "3":"type":"value3","pid":"132"
   ]

无法将 subdatas 添加到 data 。不知道如何将它们嵌入到回报中。

我尝试的另一种测试方式

get_datas = (id) ->
     get_data(id)
        .map (data) ->
            if data.type == "value1"
              return get_datas(_.get(data,"pid"))                     
            _.zipObject([data.id], [ _.omit(data, 'id')])

这给出了所有嵌套数据,但没有键(预期),如下所示

[
  [
    [
     
     
     
    ]
   
   
  ]
 
 
]

【问题讨论】:

-> 不是 javascript 所需的输出数据结构不清楚。 我的错我应该提到coffeescript 你没有返回,在第二个变体中,你返回的只是函数而不是值。 @Yaroslav 不确定我是否关注了你 return get_datas(_.get(data,"pid")) 这将返回 subset_data 元素列表 [,,] 。我试过return _.set( ,[data.id,"subset_data"], get_datas(_.get(data,"pid")) ) ,但这给了承诺问题 "isFulfilled": false, "isRejected": false 【参考方案1】:

您可以通过以下方式创建所需的结构以进行同步数据检索。

get_datas = (id) ->
  get_data(id).map ( id, data... ) -> 
    data.subset_data = get_datas(data.pid) if data.type == 'value1'
     [id]: data 

我添加了这个,因为在您的问题中,get_data 看起来是一个同步函数,在这种情况下,get_datas 不需要异步。

如果get_data 确实是异步的,那么get_datas 也将因此是异步的。这使得上面的内容稍微复杂一些,但总体上没有太大变化。

get_datas = (id) ->
  Promise.all (await get_data(id)).map ( id, data... ) ->
    data.subset_data = await get_datas(data.pid) if data.type == 'value1'
     [id]: data 

请注意,data.subset_data = 不会改变原始数组元素,因为data... 正在将所有剩余属性收集到一个新对象中。由于第二个变体是异步的,您还应该确保await 结果。

【讨论】:

以上是关于咖啡脚本承诺递归链问题的主要内容,如果未能解决你的问题,请参考以下文章

节点递归承诺永远不会退出

等待承诺链有啥问题?

节点 q 承诺递归

如何正确地打破承诺链?

异常被承诺链吞噬

使用承诺和递归迭代文件目录