使用async / await进行顺序(阻塞调用)太早返回

时间:2018-05-24 00:52:17

标签: javascript asynchronous async-await es6-promise

下面是一个简单的示例,用于演示我尝试使用fetch API的原因。我希望异步fetchAsync()会阻塞,直到它返回数据(或异常),但输出显示它没有。

constructor entering fetchAsync... ** we are here!!! ** leaving fetchAsync. finish initialization

当我的对象使用文件内容进行初始化时,我一直试图弄清楚如何在we are here之后显示完成字符串(finish initialization)。是不是等待/异步假设阻止直到它完成?

class A {
    filename = "./resources/test.json";

    constructor() {
        console.log("constructor");
        this.fetchAsync(this.filename)
            .then( data => this.initialize(data)
            ).catch(reason => console.log(reason.message))
    }

    async fetchAsync(filename) {
        console.log("entering fetchAsync...");
        let data = await (await fetch(filename)).json();
        console.log("leaving fetchAsync.");
        return data;
    }

    initialize() {
        setTimeout(() => console.log("finish initialization"), 1000)
    }
}

let a = new A();
console.log("*** we are here!!! ***");

2 个答案:

答案 0 :(得分:0)

await没有阻止 - 这将是非常用户和应用程序不友好 - 它只是等待承诺在继续之前解决,并且无法完成在顶级(尚)。如果您希望we are here仅在初始化完成后显示,那么您需要能够访问在初始化完成后解析的承诺,然后在其上调用then

您还应该确保initalize返回一个Promise,以便可以将其链接到a上的外部调用。

所以,你可以尝试这样的事情:



const dummyRequest = () => new Promise(res => setTimeout(res, 1000, 'response'));

class A {
  // filename = "./resources/test.json";
  constructor() {
    console.log("constructor");
  }
  startFetch() {
    return this.fetchAsync(this.filename || 'foo')
      .then(data => this.initialize(data)).catch(reason => console.log(reason.message))
  }
  async fetchAsync(filename) {
    console.log("entering fetchAsync...");
    // let data = await (await fetch(filename)).json();
    const data = await dummyRequest();
    console.log("leaving fetchAsync.");
    return data;
  }

  initialize() {
    return new Promise(resolve => {
      setTimeout(() => {
        console.log("finish initialization");
        resolve();
      }, 1000);
    });
  }
}

const a = new A();
a.startFetch()
  .then(() => {
    console.log("*** we are here!!! ***");
  });




构造函数不能异步,这就是我创建startFetch函数的原因。

答案 1 :(得分:0)

你必须忘记asyn chronous的意思:

class A {
  constructor() {
      this.filename = "./resources/test.json";
      console.log("constructor");
      this.fetchAsync(this.filename)
          .then( data => this.initialize(data)
          ).catch(reason => console.log(reason.message))
  }

  async fetchAsync(filename){
      console.log("entering fetchAsync...");
      let data = await fetch(filename);
      console.log("leaving fetchAsync.");
      return data.json;
  }
  initialize() {
      setTimeout(() => {console.log("finish initialization"); console.log("*** we are here!!! ***"}, 1000)
  }
}
let a = new A();