承诺完成后出口

时间:2018-03-02 16:12:41

标签: javascript promise

我想导出一个类,其初始状态取决于我无法修改的另一个模块中Promise返回的值。

以下是代码:

let e = true;

APromiseFromAnotherModule()
  .then(value => return value;);

export default class E {
  constructor() {
    if (e) {
      //...
    } else {
      //...
    }
  }
}

我还尝试将async/await封装到Promise这样的异步函数中:

let e = true;

getInitialValue = async () => {
  return await APromiseFromAnotherModule()
    .then(value => e = value;);
};

e = getInitialValue();

export default class E {
  constructor() {
    if (e) {
      //...
    } else {
      //...
    }
  }
}

但它没有意义,因为它是一个async函数,所以很明显它不起作用。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

模块导出同步完成。因此,它们不能依赖于异步操作的结果。

而且,await仅适用于函数内部。它实际上并不阻止包含函数(包含函数返回一个promise),因此无法帮助您将异步操作转换为同步操作。

处理在其设置中使用某些异步代码的模块的常用方法是导出promise并让调用代码在promise上使用.then()或者使用返回的构造函数初始化模块承诺。

代码只是伪代码,所以很难准确地告诉你真正的问题是为你展示特定的代码。

举个例子。如果要导出class定义,但在完成某些异步代码之前不希望使用类定义,则可以执行以下操作:

// do async initialization and keep promise
let e;
const p = APromiseFromAnotherModule().then(val => e = val);

class E {
    constructor() {
        if (e) {
            //...
        } else {
            //...
        }
    }
};

// export constructor function
export default function() {
   return p.then(e => {
       // after async initialization is done, resolve with class E
       return E;
   });
}

然后调用者可以像这样使用它:

import init from 'myModule';
init().then(E => {
   // put code here that uses E
}).catch(err => {
   console.log(err);
   // handle error here
});

这解决了几个问题:

  1. 模块加载后立即启动异步初始化。
  2. 在完成异步初始化之前,调用者无法使用E类,因此在准备好之前无法使用它
  3. 同一class E用于模块的所有用户
  4. 异步初始化已缓存,因此只执行一次