gpt4 book ai didi

javascript - 将事件处理程序包装在 Promise 中

转载 作者:太空宇宙 更新时间:2023-11-04 03:15:44 24 4
gpt4 key购买 nike

我有一个托管 JSON 对象数组的文件。我想将这些对象插入数据库。插入是一个异步命令,执行大约需要一秒钟。该脚本应提供插入的记录的计数。创建以下内容来模拟问题:

const fs = require('fs');
const jstream = require('JSONStream');

new Promise((res, rej) => {
let rec = 0;

try {

const stream = fs.createReadStream('./sample.json');
console.log(1);
const p = stream.pipe(jstream.parse('*'))

p.on('data', (stuff) => {
console.log(2);
console.log("New Round");
console.log(stuff);

// Simulated database insert
setTimeout(()=> rec++, 2000 );
});

p.on('end', (rec) => {
console.log(3);
res(rec);
});

p.on('error', (err) => {
console.log(4);
rej(err);
})
} catch (err) {
console.log(5);
rej(err);
}
})
.then((count) => {
console.log(6);
console.log(count);
console.log("Done loading!");
})
.catch((err) => {
console.log(7);
console.log(err);
});

当我运行脚本时,我没有得到总数。以下是我得到的输出:

1
2
New Round
{ _id: '15fb781a-d2fc-4429-82c7-8eb3e0a007b7', _name: 'bruce' }
2
New Round
{ _id: '02007ad3-2b25-46d9-a609-edacf9e151dc', _name: 'ken' }
2
New Round
{ _id: '18913a7a-18e6-484b-81cd-2f89f1558de1', _name: 'phil' }
2
New Round
{ _id: '3dab1d04-7263-41a6-ad1e-bfa9e201d377', _name: 'bob' }
2
New Round
{ _id: '9584fee5-3733-460d-a1bc-21c2ae47e78b', _name: 'luthor' }
2
New Round
{ _id: 'f676eea0-dfa2-44b5-8af7-28622b533eae', _name: 'jimmy' }
2
New Round
{ _id: 'd435a9dd-95e0-4a5f-b12f-781248fcefe4', _name: 'pauly' }
2
New Round
{ _id: '6b7d882c-7071-4cdf-8426-eb0ed25d2f02', _name: 'micky' }
3
6
undefined
Done loading!

以下是示例数据文件 (sample.json) 的内容:

[
{
"_id": "15fb781a-d2fc-4429-82c7-8eb3e0a007b7",
"_name": "bruce"
},
{
"_id": "02007ad3-2b25-46d9-a609-edacf9e151dc",
"_name": "ken"
},
{
"_id": "18913a7a-18e6-484b-81cd-2f89f1558de1",
"_name": "phil"
},
{
"_id": "3dab1d04-7263-41a6-ad1e-bfa9e201d377",
"_name": "bob"
},
{
"_id": "9584fee5-3733-460d-a1bc-21c2ae47e78b",
"_name": "luthor"
},
{
"_id": "f676eea0-dfa2-44b5-8af7-28622b533eae",
"_name": "jimmy"
},
{
"_id": "d435a9dd-95e0-4a5f-b12f-781248fcefe4",
"_name": "pauly"
},
{
"_id": "6b7d882c-7071-4cdf-8426-eb0ed25d2f02",
"_name": "micky"
}
]

最佳答案

您正在创建一个竞争条件,当 end 事件触发时,您的 promise 将得到解决,这可能会在所有插入完成之前完成。

由于您正在使用 Promise,因此您应该将插入操作包装在 Promise 中,因为这是异步的。一旦你这样做了,你就可以维护一系列可用于解决外部 promise 的 promise 。

请尝试这个:

const fs = require('fs');
const jstream = require('JSONStream');

// Simulated database insert
const insert = () => new Promise(res => setTimeout(res, 2000));

new Promise((res, rej) => {
let promises = [];

try {

const stream = fs.createReadStream('./sample.json');
console.log(1);
const p = stream.pipe(jstream.parse('*'))

p.on('data', (stuff) => {
console.log(2);
console.log("New Round");
console.log(stuff);

promises.push(insert());
});

p.on('end', () => {
console.log(3);
// v-- Resolve with a promise that waits for all
// inserts to finish
res(Promise.all(promises).then(a => a.length));
});

p.on('error', (err) => {
console.log(4);
rej(err);
})
} catch (err) {
console.log(5);
rej(err);
}
})
.then((count) => {
console.log(6);
console.log(count);
console.log("Done loading!");
})
.catch((err) => {
console.log(7);
console.log(err);
});

关于javascript - 将事件处理程序包装在 Promise 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56712501/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com