从 Rest api 异步获取数据并使用 node.js 将它们加载到 mongodb - 使用承诺

彩蝶

我和 Javascript 一起工作的不多,现在很挣扎。

简而言之:

我想从 Rest-API 检索数据并将它们批量插入到正在运行的 MongoDB 数据库的集合中。

到目前为止我的知识:

由于 Javascript 是一种单线程语言。因此,如果您希望在其他事情完成(主要是异步操作)之后再做某事,则必须使用回调。回调:回调是一个函数A,它作为参数传递给函数,并且必须在该函数的最后执行以保证A

  • 作为最新动作执行

或者

  • 必须异步检索的数据/对象可能可用,因此它们可以在 A 中使用

承诺:

是否为 Javascript 引入了一个相对较新的功能,可用于处理 Javascript 单线程性质?Promise 具有不同的状态(已完成、已拒绝、未决、已解决)。

async/await:也是一个新功能,让异步函数的工作看起来更同步,并防止过多的嵌套可能导致混淆。

我的场景:

这是一个具有使用“请求”来执行 REST 请求的函数的类。

class DataManager {
    static loadSkill(uri) {
        return new Promise((resolve, reject) => {
            const apiEndpoint = 'apiEndpoint';
            request(apiEndpoint + uri, (error, response, body) => {
                if (!error && response.statusCode === 200) {
                    resolve(body)
                } else reject(error);
            });
        });
    }
 ...
}

在以下函数中,我读取了要从 JSON 文件中检索的数据的 URI。加载和解析的数组被拆分为 100 个条目大小的数组,因为我想稍后一次批量插入 100 个对象。在内部 forEach 循环中,我尝试使用带有await的 promise 来加载技能,因此必须使用async声明该函数

function retrieveAndInsertAllSkills() {
    //DBManager.createCollection('skills');
    fs.readFile('./data/uris.json', 'utf8', function readFileCallback(err, data) {
        if (err) {
            console.log(err);
        } else {
            let obj = JSON.parse(data);

            let chunks = chunk(obj.uris, 100);

            chunks.forEach((chunk)=>{
                let skills = [];
                chunk.forEach(async (uri) => {
                    let skill = await Datamanager.loadSkill(uri);
                    skills.push(skill);
                });
                DBManager.insertMany(skills,'skills')
            })
        }
    });
}

起初,我遇到了关于 MongoDB 的错误。但我意识到错误是由于尝试插入空数组引起的。所以,老实说,我在另一个问题上遇到了类似的问题。

我尝试执行 Linux shell 命令 (sha1sum [file]) 以获取校验和。文件很大,我

class FileUtil {
    static executeCommand(command, paramsArray) {
        return new Promise((resolve, reject) => {
            let cmd = spawn(command, paramsArray);
            cmd.stdout.on('data', data => {
                resolve(data.toString());
            });
            cmd.stderr.on('data', error => {
                reject(error.toString());
            });
        });
    }
  ...
    static getSha1Sum(file){
        this.executeCommand('sha1sum', [file])
            .then((chkSum) => {
                console.log(chkSum);
                return chSum
            })
            .catch((errorMsg) =>{
                console.log(errorMsg);
                return new Error(errorMsg)});
    };
 ...
}

以下代码仅在控制台打印“未定义”。上面的代码打印了所需的结果。

async function testcheck(file) {
    try {
        let hash = await FileUtil.getSha1Sum(file);
        console.log(hash);
    }
    catch (e) {
        console.log(e);
    }
}
testcheck('/home/coloeus/Downloads/WebStom-2018.2.2.tar.gz');

所以我的问题是:我的代码有什么问题。我希望你能给我一个提示。我已经阅读了很多关于使用 Promise 的内容,但不知道为什么它不起作用。

纳奇

用 for..of 替换第二个 forEach,如下所示:

chunks.forEach(async (chunk)=>{
    let skills = [];
    for (const uri of chunk) skills.push(await Datamanager.loadSkill(uri));
    DBManager.insertMany(skills,'skills');
})

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章