从父级到子级连续执行Promise树 [英] Execute Promise tree consecutively from parent to child

查看:53
本文介绍了从父级到子级连续执行Promise树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用嵌套的Promise创建一个树形结构.

I want to create a tree structure using nested Promise's.

当promise在树结构中解析时,它将由内而外(子级然后父级)解析.我需要使从父级到子级的Promise的执行可以并行运行.

When the promises resolve in the tree structure it will resolve from the inside out (child then parent). I need to have the execution from parent to child sibling promises can run in parallel.

我想出了一种方法来解决延迟问题,方法是解决一个关闭操作,该操作将延迟已解决的Promise的操作,并从上至下递归调用每个函数.这是一个非常优雅的解决方案,但是,我可以使用任何其他约定或Functional对象来执行操作.我真的不想解决树中每个节点的闭包问题,因为这样做会增加教导人们使用它的复杂性.

I have come up with a way to delay the execution by resolving a closure that will delay the action from a resolved promise and recursively calling each function from the top down. It's a fairly elegant solution, however, is there any other convention or Functional object I can use to perform the action. I really don't want to have to resolve a closure from each node in the tree as it will increase the complexity to teach people to use it.

我宁愿不使用async/await,而只坚持使用Promise或另一个Functional JS对象.

I would prefer to not use async/await and just stick with Promise's or another Functional JS object.

第一个示例将显示嵌套Promises的已解决顺序.

This first example will show the resolved order of the nested Promises.

let order = 0
const promiseTree = (name, children) => 
  Promise.all([
    new Promise(res => res(`${name} order:${order++}`)),
    children && Promise.all(children)
  ])

promiseTree('root', [
  promiseTree('child', [
    promiseTree('grandchild', [
      promiseTree('great grandchild sibling 1'),
      promiseTree('great grandchild sibling 2'),
    ])
  ])
])
.then(console.log)

<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?concise=true"></script>

如果您解决了关闭问题,则当所有承诺均完成后,便可以递归调用回调.

If you resolve a closure, then recursively call the callbacks once all promises are complete the order can be corrected.

let order = 0
const promiseTree = (name, children) => 
  Promise.all([
    // --------------------- resolve a closure with the resolved value contained
    new Promise(res => res(() => `${name} order:${order++}`)),
    children && Promise.all(children)
  ])

// flatMap over the tree, if it's a function call it and return the result
const recursivelyCall = x => 
  Array.isArray(x)
    ? x.map(recursivelyCall)
    : typeof(x) === 'function' ? x() : x

promiseTree('root', [
  promiseTree('child', [
    promiseTree('grandchild', [
      promiseTree('great grandchild sibling 1'),
      promiseTree('great grandchild sibling 2'),
    ])
  ])
])
// traverse the returned values and call the functions in declared order
.then(recursivelyCall)
.then(console.log)

<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?concise=true"></script>

欢呼

推荐答案

第一个代码段中的模式所涉及的问题是,最里面的嵌套函数(参数)首先被执行.在 https://astexplorer.net/#/bist/268805 5a2def5def7d8ee91c052d9733bc7a37c63a6f67 https://github.com/tc39/ecma262/issues/1397 .

The issue with the pattern at the code at the first snippet is that the inner-most nested function (argument) is executed first; see and highlight line 15 at https://astexplorer.net/#/gist/777805a289e129cd29706b54268cfcfc/5a2def5def7d8ee91c052d9733bc7a37c63a6f67, https://github.com/tc39/ecma262/issues/1397.

我宁愿不使用异步/等待,而只坚持使用Promise 或其他功能性JS对象.

I would prefer to not use async/await and just stick with Promise's or another Functional JS object.

目前尚不清楚为什么不考虑该选项. async函数是Promise的实例.鉴于要求async/await是可行的解决方案.

It is not clear why that option is excluded from consideration. An async function is an instance of Promise. Given the requirement async/await is a viable solution.

console.log((async() => void 0)() instanceof Promise);

const fn = async() => {
  let order = 0
  const promiseTree = name =>
    new Promise(res => res(`${name} order:${order++}`))

  const res = [await promiseTree('root'), [
    await promiseTree('child'), [
      await promiseTree('grandchild'), [
        await promiseTree('great grandchild sibling 1')
      , await promiseTree('great grandchild sibling 2')
      ]
    ]
  ]];
  return res;
}

fn()
.then(console.log)

这篇关于从父级到子级连续执行Promise树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆