【问题标题】:Typescript async function with foreach, inside foreach, calling another async function带有foreach的Typescript异步函数,在foreach内部,调用另一个异步函数
【发布时间】:2018-09-06 00:11:48
【问题描述】:

最近我偶然发现了一个异步函数的问题。

我正在使用 2 个函数,它们都是异步的。 问题是返回值是一个承诺, 因为我不能在 foeach 循环中等待它。 我已经尝试使两个 foreach 都异步,但这不起作用 因为它给我提供了虚假数据。

private getAllProperties = async (props?: IPageDetailsProps) => {
props = props || this.props;
let web = new Web(props.context.pageContext.web.absoluteUrl);
let id = 2;
let pageProps = await web.lists.getByTitle("Site Pages").items.filter(`Id eq '${id}'`).get();
let fieldProps = await web.lists.getByTitle("Site Pages").fields.filter(`Group eq 'Template Columns' or InternalName eq 'Title' or InternalName eq 'Created' or InternalName eq 'Author' or InternalName eq 'Modified' or InternalName eq 'Editor'`).get();
let regionalSettings = await web.regionalSettings.get();
let fieldsList: Array<any> = [];
let obj = JSON.parse(props.fields.toString());

fieldProps.forEach(value => {
  obj.forEach(field => {
    if (field === value.InternalName) {
      let item: any = {};
      item.title = value.Title;
      item.internalName = value.InternalName;
      item.typeAsString = value.TypeAsString;
      if (item.typeAsString === "DateTime") {
        let formatOptions: Intl.DateTimeFormatOptions = {};
        formatOptions.hour12 = !regionalSettings.Time24;
        let date = new Date(pageProps[0][field]);
        item.Data = date.toLocaleString(regionalSettings.LocaleId, formatOptions);
      }
      if (item.typeAsString === "Text" || item.typeAsString === "Note") {
        let text = pageProps[0][field];
        item.Data = text;
      }
      if (item.typeAsString === "User") {
        let personId = field + "Id";
        let user = this.getPersonFromId(pageProps[0][personId])
        item.Data = user;
       // Problem is here, by the fact that the return value from 
       // getPersonFromId is a promise, 
       // since i cant await for it here.
       // I have tried making the both foreach async, but that does not work 
       // as it feeds me bogus data.
       // What i want to do is not do anything until i have an answer
      }
      if (item.typeAsString === "TaxonomyFieldType") {
        item.Data = pageProps[0][field].Label;
      }
      if (item.typeAsString === "TaxonomyFieldTypeMulti") {
        let items = pageProps[0][field];
        let terms = "";
        items.forEach(element => {
          terms += element.Label + "   ";
        });
        item.Data = terms;
      }
      fieldsList.push(item);
    }
  });
});

功能2

private getPersonFromId = async (id: number) => {
let queryUrl = this.props.context.pageContext.site.absoluteUrl + `/_api/web/getuserbyid(${id})`;
const spSearchConfig: ISPHttpClientConfiguration = {
  defaultODataVersion: ODataVersion.v3
};
let personResponse = await this.props.context.spHttpClient.get(queryUrl, SPHttpClient.configurations.v1.overrideWith(spSearchConfig));
let personResult = await personResponse.json();

let person: any = {};
person.name = personResult.Title;
person.mail = personResult.Email;

return person;

}

【问题讨论】:

  • 你试过了吗let user = await this.getPersonFromId(pageProps[0][personId])

标签: typescript asynchronous sharepoint foreach


【解决方案1】:

异步函数不能很好地与forEach 配合使用,因为forEach 没有机制来等待异步回调在任何给定的迭代中完成。您需要执行以下操作之一:

  • 编写您自己的 forEach 的异步版本(不要太复杂;请参阅 here 以获得一个很好的示例)
  • 使用现有的异步循环库(如async-foreach
  • 写一个很好的旧 for...of 循环,如这个 SO 答案所示:Using async/await with a forEach loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 2018-11-17
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多