Javascript承诺链与重复逻辑附加到同一项目数组中。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript承诺链与重复逻辑附加到同一项目数组中。相关的知识,希望对你有一定的参考价值。

链的各个部分根据结构的不同而重复。例如,网站可以有两个子网站,每个子网站有两个列表。这意味着最后一个链会触发四次。在所有内部变化执行后,我在哪里可以得到模板对象,以便我有完整的模板集合?

    let promises = [];
    let templates:ITemplate[] = [];

    pnp.sp.web.webs.get().then(sites => {
      sites.forEach(site => {
        pnp.sp.site.openWebById(site.Id).then(result => {
          result.web.lists.get().then(lists => {
            lists.forEach(list => {
              promises.push(result.web.lists.getByTitle(list.Title).items.get());
            });
            Promise.all(promises)
            .then((results) => {
               // This runs multiple times which makes sense but I need the final templates array
               results.forEach(items => {
                items.forEach(item => {            
                  let template:ITemplate= {
                    Title:item.Title,
                    ...
                    ...
                  };
                  templates.push(template);
                });

                // If I add function here it runs multiple times which is not the desired outcome
                doSomethingWithTemplates(templates);
              });
            })
          })
        })
      });
    })

// Then do something with templates item collection that is a single item array with all items
答案

我相信你可以从你所遇到的问题中看到链式承诺的缺点--也许是类似于我下面的方法,用 async/await 会让你更清楚如何解决问题?

Async/await 是有效地建立在承诺之上的,而且还是使用承诺。 如果你还不知道的话,可以给你一个概念。

async function insertName():Promise<ITemplate[]> {
    let promises = [];
    let templates:ITemplate[] = [];
    const sites = await pnp.sp.web.webs.get()
    sites.forEach(site => {
        const result = await pnp.sp.site.openWebById(site.Id)
        const lists = await result.web.lists.get()
        lists.forEach(list => {
            const toPush = await result.web.lists.getByTitle(list.Title).items.get()
            promises.push(toPush);
        })
        const results = await Promise.all(promises)
        results.forEach(items => {
            items.forEach(item => {            
                let template:ITemplate= {
                    Title:item.Title,
                    ...
                    ...
                };
                templates.push(template);
            });
            doSomethingWithTemplates(templates);
        });
    })
    return templates
}
const templates: ITemplate[] = await insertName()

以上是关于Javascript承诺链与重复逻辑附加到同一项目数组中。的主要内容,如果未能解决你的问题,请参考以下文章

异步 JavaScript - 回调与延迟/承诺 [重复]

在JavaScript中将一个数组附加到另​​一个数组[重复]

Javascript,如何等待多个承诺[重复]

JavaScript将回调转换为承诺[重复]

JavaScript ES6承诺循环[重复]

JavaScript将属性附加到对象[重复]