Node.js Promise.all()和.map出现问题,出现意外结果

Node.js Promise.all()和.map出现问题,出现意外结果,node.js,dictionary,asynchronous,promise,Node.js,Dictionary,Asynchronous,Promise,我已经读了所有关于承诺的书,我测试了多个线程的多个解决方案,但我仍然无法让它工作 我试图迭代文件夹中的文件,获取xml内容,使用XMLJS模块将其转换为js对象,然后将它们添加到数组中。 这是我最后一次尝试(大约30次中的一次) 我错过了什么? 我以为readdir正在被调用,然后回调返回,这就是我等待Promise.all的地方,然后使用.map对所有内容进行迭代并返回值,该值应(?)返回一个要解析的承诺 然后在所有问题都解决之后,它才应该继续运行到console.log(),但由于某种原因,

我已经读了所有关于承诺的书,我测试了多个线程的多个解决方案,但我仍然无法让它工作

我试图迭代文件夹中的文件,获取xml内容,使用XMLJS模块将其转换为js对象,然后将它们添加到数组中。 这是我最后一次尝试(大约30次中的一次)

我错过了什么? 我以为readdir正在被调用,然后回调返回,这就是我等待Promise.all的地方,然后使用.map对所有内容进行迭代并返回值,该值应(?)返回一个要解析的承诺

然后在所有问题都解决之后,它才应该继续运行到console.log(),但由于某种原因,在我运行服务器的那一刻,它立即跳到console.log(),就好像所有承诺都已经解决了一样

将console.log()放入readFile方法时,它仍在运行


我很困惑,有人能指出我的错误吗?

这里有几件事。第一个承诺。所有承诺都包含一系列你没有给出的承诺。在您的files.map中,您不会在map回调函数中返回任何内容。所以试试这个:

files.map((file) => {
        return fs.readFile(filePath, 'utf8', async(err, data) => {
            return await xmljs.xml2js(data , {compact : true).RequestFileHatasDM;
        })
    })
此外,在异步函数中返回承诺时,您可以执行以下操作:

return xmljs.xml2js()
而不是:

return await xmljs.xml2js()
容易错过的事。我鼓励您设置一个调试环境,这样您就可以逐步完成函数并查看代码中的不同值。它确实可以为您节省一些调试代码的时间

我喜欢VSCodes调试器:


这种代码可能会让人非常困惑。它可以更容易地创建一个函数,该函数将返回承诺并接受文件路径作为输入

我们可以使用创建的promisified版本,它更容易阅读生成的代码,也更紧凑

然后,我们可以使用Promise.all对通过该函数映射文件路径的结果进行分析

例如:

const fs = require('fs');
const path = require('path')
const xmljs = require('xml-js');
const { promisify } = require ('util');

const readFilePromise = promisify(fs.readFile);
const readDirPromise = promisify(fs.readdir);

// Replace as appropriate.
const folderPath = 'test_dir';

async function xmlFile2js(path) {
    const data = await readFilePromise(path, { encoding: 'utf-8'});
    return xmljs.xml2js(data, { compact: true});
}

async function readXmlFiles(folderPath) {
    try {
        const files = await readDirPromise(folderPath);
        const filePaths = files.map(file => path.join(folderPath, file));
        const promiseArray = filePaths.map(filePath => xmlFile2js(filePath));
        const xmlArray = await Promise.all(promiseArray);
        return xmlArray;
    } catch (err) {
        console.error("readXmlFiles: An error occurred:", err);
    }
}

async function testReadXmlFiles() {
    const xmlArray = await readXmlFiles(folderPath);
    console.log("testReadXmlFiles: xmlArray:", JSON.stringify(xmlArray, null, 4));
}

testReadXmlFiles();

你好我一直试图让它工作,但没有任何效果,我尝试设置静态路径,不使用readdir,承诺从未解决,当使用与上述相同的代码并添加return时,我仍然得到一个未定义的数组@特里的回答很好,但我想在不使用promisify更好地理解承诺的情况下让它发挥作用。你能详细解释一下你的答案吗?对不起,我本应该比以前多复习一下我的答案@特里的回答是一个很好的解决方案。将承诺与回调一起使用是两种不同的风格,会导致非常混乱的代码。提倡像readFile这样的方法是一种很好的方法,可以将所有内容保持在一种风格中。根据您正在使用的节点的版本,您可以查看这一点。它只负责承诺部分。我明白了。。。谢谢这个成功了!我理解代码,但如果你能指出原始代码中的错误,我会很高兴,因为我也想从我的错误中学习,我明白了!我现在遇到了另一个问题,我尝试将整个代码移动到一个单独的异步方法generateCompleteXmlFile中,然后在将文件添加到文件夹时从server.js调用它(使用watched),我将
console.log(xmlArray)
更改为
return xmlArray
,并等待它,但它没有等待。知道为什么吗?看起来有点像这样:
let result=await xmljs.generateCompleteXmlFile()
then
console.log(result)
result是未定义的我向generateCompleteXmlFile添加了一个回调并修复了它,这是正确的做法吗?那么我如何仅用承诺来解决这种情况呢?当我尝试像这样等待
let result=wait xml2js.generatecompletemmlfile()
和下一行我做了
console.log(result)
时,我几乎立刻收到了
undefined
,它没有等待,我也不知道为什么会这样,感谢您抽出这么多空闲时间来帮助我!我已经试过你的方法了,但是由于某种原因,
wait
不起作用,
console.log(“testReadXmlFiles:…)
会立即解决,
未定义
,这就是为什么我如此困惑并求助于回调
const fs = require('fs');
const path = require('path')
const xmljs = require('xml-js');
const { promisify } = require ('util');

const readFilePromise = promisify(fs.readFile);
const readDirPromise = promisify(fs.readdir);

// Replace as appropriate.
const folderPath = 'test_dir';

async function xmlFile2js(path) {
    const data = await readFilePromise(path, { encoding: 'utf-8'});
    return xmljs.xml2js(data, { compact: true});
}

async function readXmlFiles(folderPath) {
    try {
        const files = await readDirPromise(folderPath);
        const filePaths = files.map(file => path.join(folderPath, file));
        const promiseArray = filePaths.map(filePath => xmlFile2js(filePath));
        const xmlArray = await Promise.all(promiseArray);
        return xmlArray;
    } catch (err) {
        console.error("readXmlFiles: An error occurred:", err);
    }
}

async function testReadXmlFiles() {
    const xmlArray = await readXmlFiles(folderPath);
    console.log("testReadXmlFiles: xmlArray:", JSON.stringify(xmlArray, null, 4));
}

testReadXmlFiles();