我正在解析CSV并处理每条记录,以使用Mongoose将其插入到我的MongoDB中。我已经正确地从CSV中获取了一个数组,但是当我开始使用forEach(和async / await)对其进行迭代时,它就在那里停止了。
这是我的代码:
const csv = require('csv-parser');
const fs = require('fs');
const Customer = require('../../app/models/Customers');
const projects = [];
const proccessRecords = async () => {
try {
const usableProjects = projects.filter((project) => project['cust_number customer']);
const customerNames = [...new Set(usableProjects.map((item) => item['Parent Name']))];
await customerNames.forEach(async (customerName) => {
console.log('Point 1');
const existingCustomer = await Customer.find({Name: customerName});
console.log('Point 2'); //<======= THIS CODE IS NEVER REACHED
if (existingCustomer.length > 0) {
console.log(`${customerName} already exists. Skipping...`);
return;
}
const customerRecord = usableProjects.find((project) => project['Parent Name'] === customerName);
const newCustomer = {
Name: customerName,
Source: 'CSV',
Initials: customerRecord.Initials,
Code: customerRecord.Codename,
};
const newCustomerRecord = await Customer.create(newCustomer);
if (newCustomerRecord) {
console.log(`Customer ${newCustomerRecord._id} created`);
}
});
} catch (err) {
console.log(err);
}
};
fs.createReadStream('customer_table.csv')
.pipe(csv())
.on('data', async (data) => projects.push(data))
.on('end', async () => {
proccessRecords();
});
这是输出:
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
Point 1
我知道这可能与我未处理的同步/异步代码有关。但是我无法修复它。预先感谢。
答案 0 :(得分:0)
我同意@JaromandaX,因为每个都不支持诺言,并且不支持异步/等待。请改用map
。
答案 1 :(得分:0)
数组 ClassLoader classLoader = getClass().getClassLoader();
try {
InputStream in = classLoader.getResourceAsStream("/assets/baseline_close_black_18dp.png");
Image image = new Image(in);
ImageView imageView= new ImageView(image);
} catch (Exception ex) {
}
不返回任何内容,因此,您无法等待它们。如果您要等待一系列的诺言,那就去forEach
吧。但是,请注意,应将其与map
Promise.all
现在,这将并行运行所有item.fetch调用。在大多数情况下,这是首选方式。但是,如果要连续运行item.fetch调用,则应改用for循环。
async function example(arr) {
await Promise.all(
// Assume item.fetch() returns a promise
arr.map(item => item.fetch())
);
}
答案 2 :(得分:0)
首先,让我们将try-catch
放在Customer.find()
上
(为清楚起见,我将简化您的代码。并将Customer.find()
替换为f()
)
async function success() { return "Hurrah!" }
async function failure() { throw new Error("Oops!") }
const customerNames = [1, 2, 3]
const proccessRecords1 = async (f) => {
try {
await customerNames.forEach(async (customerName) => {
try {
console.log('Point 1');
const existingCustomer = await f()
console.log('Point 2', existingCustomer);
// ...
} catch (err) {
console.log('Point 3', err);
}
});
} catch (err) {
console.log('Point 4', err);
}
};
setTimeout(() => proccessRecords1(success), 0);
输出:
Point 1
Point 1
Point 1
Point 2 Hurrah!
Point 2 Hurrah!
Point 2 Hurrah!
如您所见,如果达到f = success
的“点2”。因此,这是第一个问题:您的Customer.find()
失败了,您看不到异常。
让我们尝试抛弃f()
,只是为了证明重点...
setTimeout(() => proccessRecords1(failure), 100);
输出:
Point 1
Point 1
Point 1
Point 3 Error: Oops!
Point 3 Error: Oops!
Point 3 Error: Oops!
是的,如果f()
失败,我们将永远无法到达“第2点”。但是现在我们确实在“第3点”中看到了一个错误。所以我们可以在这里停止。
但是,让我们尝试在顶级proccessRecords()
上捕获异常,并进入“第4点”。
如前所述,forEach()
不返回值。让我们尝试map()
const proccessRecords2 = async (f) => {
try {
await customerNames.map(async (customerName) => {
console.log('Point 1');
const existingCustomer = await f()
console.log('Point 2', existingCustomer);
// ...
});
} catch (err) {
console.log("Point 4", err);
}
};
setTimeout(() => proccessRecords2(failure), 200);
输出:
Point 1
Point 1
Point 1
Uncaught (in promise) Error: Oops!
Uncaught (in promise) Error: Oops!
Uncaught (in promise) Error: Oops!
没有运气。这是因为map()
确实返回了一个值,但这是一个Array
,而不是Promise
。您不能await
使用Promise-s数组,但是可以使用Promise.all()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
const proccessRecords3 = async (f) => {
try {
await Promise.all(customerNames.map(async (customerName) => {
console.log('Point 1');
const existingCustomer = await f()
console.log('Point 2', existingCustomer);
// ...
}));
} catch (err) {
console.log("Point 4", err);
}
};
setTimeout(() => proccessRecords3(failure), 300);
输出:
Point 1
Point 1
Point 1
Point 4 Error: Oops!
Point 4 Error: Oops!
Point 4 Error: Oops!
那。将await customerNames.forEach(...)
替换为await Promise.all(customerNames.map(...)
,一切顺利。