承诺完成后导出 [英] exporting after promise finishes

查看:31
本文介绍了承诺完成后导出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to export a class which initial state depends on a value returned from a Promise in another module i cannot modify.

代码如下:

let e = true;

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

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

我也尝试过使用 async/awaitPromise 封装成这样的异步函数:

I also tried with async/await encapsulating the Promise into an async function like this:

let e = true;

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

e = getInitialValue();

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

但这没有意义,因为那个是 async 函数,所以显然它不起作用.

But it doesn't make sense because that one is an async function so obviously it doesn't work.

我错过了什么?

推荐答案

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

module exports are done synchronously. So, they cannot depend upon the results of an asynchronous operation.

而且,await 只在函数内部起作用.它实际上并没有阻塞包含函数(包含函数返回一个承诺),因此也不会帮助您将异步操作转换为同步操作.

And, await only works inside a function. It doesn't actually block the containing function (the containing function returns a promise) so that won't help you make an async operation into a synchronous one either.

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

The usual ways to deal with a module that uses some async code in its setup is to either export a promise and have the calling code use .then() on the promise or to initialize the module with a constructor function that returns a promise.

代码只是伪代码,因此很难确切地说出真正的问题是什么,无法向您展示适合您情况的特定代码.

The code is only pseudo code so it's hard to tell exactly what your real problem is to show you specific code for your situation.

举个例子.如果你想导出一个 class 定义,但不希望在一些异步代码完成之前使用类定义,你可以这样做:

As an example. If you want to export a class definition, but don't want the class definition used until some async code has completed, you can do something like this:

// 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;
   });
}

调用者可以这样使用它:

The caller could then use it like this:

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. 异步初始化被缓存,所以它只完成一次

这篇关于承诺完成后导出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆