我不喜欢到目前为止我所看到的任何东西...

模组

import lineReader from 'line-reader'

let bigFile = './huge-file.csv'

export default class DooDad {

    constructor() {
        this.dictionary = new Map()
        // Something like this seems like it'd be nice...
        // await this.load()
    }

    load() {
        return new Promise((resolve, reject) => {
            lineReader.eachLine(bigFile, (line, last) => {
                // this.dictionary = The contents of huge-file.csv
            })
        })
    }

    doStuff(foo) {
        // Uses this.dictionary to do something interesting
        // Problem: Unusable without first calling and waiting for this.load()
    }
}


用法

import DooDad from '../doodad'

let doodad = new DooDad()

// We have to first call and wait for load() before doodad is useable
doodad.load().then(x => {
    doodad.doStuff()
})


似乎您要么想要...

1)使加载同步

2)在DooDad上创建一个静态create函数,该函数返回一个可解析为DooDad的新实例的promise

3)使构造函数返回一个Promise(似乎很奇怪)Asynchronous constructor

4)完成加载后发出事件

5)保持现状

6)????

最佳答案

doodad.load().then()对我来说很有意义。您不希望构造函数异步,因此让.load()成为异步内容所在是很有意义的。

我看到的另一种模式是您导出一个工厂类型的函数,该函数返回一个诺言,当该诺言得到解决时,已解决的值就是您完全形成的对象。这样做的好处是,在完成异步工作之前,无法访问对象,并且在准备好之前,通过调用代码来尝试使用它也不会产生诱惑。

import makeDooDad from '../doodad'

makeDooDad().then(doodad => {
   // you only get access to the object here after it's been fully
   // initialized
   doodad.doStuff();
});


并且,makeDooDad()工厂函数在模块内部执行以下操作:

function makeDooDad() {
   let d = new DooDad();
   // fully initialize the doodad object before resolving the promise
   // and before returning the object
   return d.load().then(() => {
       // let the object itself by the resolved value
       return d;
   });
}


至于其他选择:


  使加载同步


仅当仅在服务器启动时完成此操作才可以。通常,在服务器启动时执行一些同步I / O并没有实际成本,并且通常使事情变得简单得多。例如,require()本身执行同步I / O。


  在DooDad上创建一个静态create函数,该函数返回一个可解析为DooDad的新实例的promise


从本质上讲,这就是我上面建议的带有工厂功能的内容。这通常是一个不错的选择。


  使构造函数返回Promise(似乎很奇怪)异步构造函数


不,真的不想要那样做。构造函数应该返回对象,而不是诺言。使用工厂函数返回承诺。


  完成加载后发出事件


还有其他一些代码可以执行此操作,例如创建writeStream,并在实际打开流时在该流上发出open事件。但是,在承诺时代,这不是我最喜欢的为尚未使用大量事件的其他类型的对象做事的方式。


  顺其自然


可以,但是我更喜欢返回promise的工厂函数。

关于node.js - 对于需要异步加载大文件然后才有用的 Node 模块,是否存在一种通用模式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46457058/

10-11 05:05