Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
82 views
in Technique[技术] by (71.8m points)

javascript - Async is out of sync

I have a button that makes an http.get on click, and then displays some data, although my async/awaits seem to not be synchronized correctly.

For a reason I haven't quite figured out yet, this.tabRows = file.contents will be called before loadDateFolderFileContents() completes. Am I missing an await somewhere?

  async ngAfterViewInit() {
    if (!this.drawn) {
        if(!file.contents){
          await this.dataLakeService.loadDateFolderFileContents(file.parentFolder);
        }
        this.tabRows = file.contents;
        this.redraw();
    }
  }

  public async loadDateFolderFileContents(dateFolder: folder) {
    await date.files.map(async file => {
      file.contents = await this.getFileContents(dateFolder.name, file.name);
    });
  }

  public async loadDateFolderFileContents(dateName: string, fileName: string): Promise<any> {
    var url = this.buildUrl(dateName, fileName);
    var fileContents = {};
    await this.http.get<any>(url).toPromise()
      .then(contents => { 
        fileContents = contents; 
      })
      .catch(e => { 
        console.log(`Error retreiving file contents from url ${url}. Exception:${e}`); 
      });
    return fileContents;
  }
question from:https://stackoverflow.com/questions/65893160/async-is-out-of-sync

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you use await in a map, map will always return an array of promise. This is because asynchronous functions always return promises.
Since map always return promises (if you use await), you have to wait for the array of promises to get resolved. You can do this with await Promise.all(arrayOfPromises), after all promises are resolved, Promise.all returns a single promise.
below is your updated code

async ngAfterViewInit() {
    if (!this.drawn) {
        if(!file.contents){
          await this.dataLakeService.loadDateFolderFileContents(file.parentFolder);
        }
        this.tabRows = file.contents;
        this.redraw();
    }
  }

  public async loadDateFolderFileContents(dateFolder: folder) {
    await Promise.all(date.files.map(async file => {
      file.contents = await this.getFileContents(dateFolder.name, file.name);
    }));
  }

  public async loadDateFolderFileContents(dateName: string, fileName: string): Promise<any> {
    var url = this.buildUrl(dateName, fileName);
    var fileContents = {};
    await this.http.get<any>(url).toPromise()
      .then(contents => { 
        fileContents = contents; 
      })
      .catch(e => { 
        console.log(`Error retreiving file contents from url ${url}. Exception:${e}`); 
      });
    return fileContents;
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...