嵌套数组中的节点JS Promise.all和forEach

时间:2017-11-28 11:56:33

标签: node.js typescript npm promise

在带有typescript的Node应用程序中,我需要遍历一个数组,然后在循环中调用一个异步函数来获取有关数组中每个项目的相关项的信息。为每个相关项调用该函数以在relatedItems数组中获取其标题。

我能够检索第二级数组(relatedItems)的promises,但不知道如何实现当时的顶级结束。

如何通过promise.all达到我的目标。

var Inputarray = [
    {   Category: "cat1"
        relatedItems: [
            {id: "1"},
            {id: "2"},
            {id: "3"}
        ]
    },
    {
        Category: "cat2"
        relatedItems: [
            {id: "1"},
            {id: "2"},
            {id: "3"}
        ]
    }
];


var wantedresult= [
    {   Category: "cat1"
        relatedItems: [
            {Title: "xxx"},
            {Title: "yyy"},
            {Title: "zzz"}
        ]
    },
    {
        Category: "cat2"
        relatedItems: [
            {Title: "ttt"},
            {Title: "kkk"},
            {Title: "mmm"}
        ]
    }
];


private GetAllRelattedItems(data: IListItem[]): any{  


      let rendredItems: RelatedItem[] = new Array();



              data.forEach(item => {


                  let relatedItemsinfos : relatedItemInfos[]=item.Children;

                     let localTab:relatedItem[]=new Array();

                      let newItem = {
                              Category:item.Category,              
                              Children: []           
                      };

                    var promises = [];
                    relatedItemsinfos.forEach(relatedItemsInfositem =>{
                        promises.push(this.GetRelatedItem(relatedItemsInfositem.WebId,relatedItemsInfositem.ListId,relatedItemsInfositem.ItemId));
                    });
                     Promise.all(promises).then(function(response) {

                        response.forEach(obj=>{
                          let newNode: relatedItem ={
                            Title :Obj.Title,

                          };

                          newItem.Children.push(newNode);

                        });


                        rendredItems.push(newItem);


                    });


              });

} 


private  GetRelatedItem(id:string) : Promise<relatedItem> {

  return new Promise((resolve) => {

    pnp.sp.site.openWeb()
    .then(web => {
    //this.getWeb()
    //.then((web) => {

      return web.web.lists.getList().get();     //w.web.lists.getById("").get().then(r => {
    })
    .then((list) => {
      return this.getItem(list,id);
    })
    .then((item) => {

      resolve(item);
    });
  });
}

2 个答案:

答案 0 :(得分:0)

您应该在顶层使用Promise.all并返回数据数组中每个项目的承诺:

private GetAllRelattedItems(data: IListItem[]): any {
  //..
  let allData = data.map(item => {
    //..
    return Promise.all(promises).then(function (response) {
      //..
    });
  });
  Promise.all(allData).then (_=> { /* After all data is retrieved */})
}

答案 1 :(得分:0)

由于您使用的是Typescript,更好的方法是利用async/await使代码更具可读性:

private async GetAllRelattedItems(data: IListItem[]): Promise<RendredItem[]> {
  let allData = data.map(async item => {
    let relatedItemsinfos: relatedItemInfos[] = item.Children;

    let localTab: relatedItem[] = new Array();

    let newItem = {
      Category: item.Category,
      Children: []
    };

    var response = await Promise.all(relatedItemsinfos.map(relatedItemsInfositem => {
      return this.GetRelatedItem(relatedItemsInfositem.WebId);
    }));

    newItem.Children = response.map(entry => ({
        Title: entry.value[0].Title,
        FileLeafRef: entry.value[0].FileLeafRef,
        Modified: entry.value[0].Modified,
        FileRef: entry.value[0].FileRef,
        FieldValuesAsText: {
          FileRef: entry.value[0].FileRef,
        }
    }));
    return newItem;

  });
  var result = await Promise.all(allData);
  // After all results are done
  return result
}

private async GetRelatedItem(id: string): Promise<{ value: relatedItem[] }> {
    const web = await pnp.sp.site.openWeb()
    const list = await web.web.lists.getList().get();     //w.web.lists.getById("").get().then(r => {
    return await this.getItem(list,id);
}

// Placeholder
public getItem(list: any[], id: string ): Promise<{ value: relatedItem[] }>{
  return Promise.resolve({
    value : []
  });
}

注意我根据使用情况猜测了一些类型,您应该检查以确保它们是正确的。