【发布时间】:2019-11-01 23:13:07
【问题描述】:
我正在使用 Nodejs。我有一个异步的 forEach,因为我必须在 forEach 中等待结果。结果,我需要等待 forEach 完成,然后继续循环的结果。我找到了几种等待 forEach 的解决方案,其中之一是使用 Promises。我确实这样做了,并且创建了这些承诺,但是,在 forEach(以及承诺)完成之后的代码从未真正执行过(console.log 未打印)。 NodeJS 函数刚刚结束,没有任何错误。
这是我的代码:
var Client = require('ssh2').Client;
// eslint-disable-next-line no-undef
var csv = require("csvtojson");
// eslint-disable-next-line no-undef
var fs = require("fs");
// eslint-disable-next-line no-undef
const config = require('./config.json');
// eslint-disable-next-line no-undef
const os = require('os');
let headerRow = [];
let sumTxAmount = 0;
const filenameShortened = 'testFile';
let csvLists = [];
let csvFile;
const options = {
flags: 'r',
encoding: 'utf8',
handle: null,
mode: 0o664,
autoClose: true
}
var conn = new Client();
async function start() {
const list = await getCSVList();
let content = fs.readFileSync('./temp.json', 'utf8');
content = JSON.parse(content);
var promises = list.map(function(entry) {
return new Promise(async function (resolve, reject) {
if (!content['usedFiles'].includes(entry.filename)) {
const filename = entry.filename;
csvFile = await getCsv(filename);
csvLists.push(csvFile);
console.log('here');
resolve();
} else {
resolve();
}
})
});
console.log(promises)
Promise.all(promises)
.then(function() {
console.log(csvLists.length, 'length');
})
.catch(console.error);
}
start();
“这里”打印一次(不是 8 次,因为数组长度为 8),但创建了 8 个 promise。我打印数组长度的下部未执行。
谁能告诉我我做错了什么?我是否错误地使用了 Promises 和 forEach,因为我必须在 forEach 中进行等待?
注意:getCSVList() 和 getCsv() 是从 sftp 服务器获取 Csv 的函数:
function getCSVList() {
return new Promise((resolve, reject) => {
conn.on('ready', function () {
conn.sftp(function (err, sftp) {
if (err) throw err;
sftp.readdir(config.development.pathToFile, function (err, list) {
if(err) {
console.log(err);
conn.end();
reject(err);
} else {
console.log('resolved');
conn.end();
resolve(list);
}
})
})
}).connect({
host: config.development.host,
port: config.development.port, // Normal is 22 port
username: config.development.username,
password: config.development.password
// You can use a key file too, read the ssh2 documentation
});
})
}
function getCsv(filename) {
return new Promise((resolve, reject) => {
conn.on('ready', function () {
conn.sftp(function (err, sftp) {
if (err) reject(err);
let csvFile = sftp.createReadStream(`${config.development.pathToFile}/${filename}`, options);
// console.log(csvFile);
conn.end();
resolve(csvFile);
})
}).connect({
host: config.development.host,
port: config.development.port, // Normal is 22 port
username: config.development.username,
password: config.development.password
// You can use a key file too, read the ssh2 documentation
});
});
}
所有控制台日志在我的控制台中的输出是:
`➜ node server.js
resolved
[ Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> } ]
here`
【问题讨论】:
-
可能
getCsv会比getCSVList更有趣,因为这似乎是它被屏蔽的地方。 -
@JeffRSon 我现在添加了它
-
我认为您并没有真正从流中阅读。您应该订阅其“数据”事件或将其通过管道传输到可写流。可能在结束连接之前。
-
var
csvLists定义在哪里?我试图通过在start()函数范围内声明const csvLists = []在本地重现您的代码,它工作得很好...... -
@k0pernikus 我做了,但后来用户要求更多代码。所以我添加了它
标签: javascript node.js promise