我和 Javascript 一起工作的不多,现在很挣扎。
简而言之:
我想从 Rest-API 检索数据并将它们批量插入到正在运行的 MongoDB 数据库的集合中。
到目前为止我的知识:
由于 Javascript 是一种单线程语言。因此,如果您希望在其他事情完成(主要是异步操作)之后再做某事,则必须使用回调。回调:回调是一个函数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] 删除。
我来说两句