NodeJS 如何正确地链接这些.then语句,以便它们按正确的顺序解析?

plicqrtu  于 2023-02-08  发布在  Node.js
关注(0)|答案(2)|浏览(185)

我正在做的任务是设计一个Node.js程序,它向用户提供命令行提示,并使用输入编写一个组织良好的README标记文件。提示是使用Inquirer NPM创建的。代码从Inquirer提示开始,然后是一个或多个.then语句使用FS的“writeFile”和“appendFile”创建文件,并以特定顺序添加元素。出于某种原因,无论我做什么,我似乎都不能让我的代码以正确的顺序将这些元素添加到新文件中。我最初将所有元素都放在一个.then语句下,但是后来我想如果我给每一项附加它自己的“.then”并把它们链接在一起,这个bug就会被修复。但是输出仍然是错误的--事实上,它似乎每次都以不同的随机顺序出现,这里有一些then语句--整个代码块相当长,所以希望它能提供足够的上下文,你也可以想象它附加到一系列的查询提示符上。

.then((response) => {
    fs.writeFile('./output/README.md', '', (err) => err ? console.log(err) : null);
    return response;
  })
  .then((response) => {
    if(response.title) {
        fs.appendFile('./output/README.md', `# ${response.title}\n`, (err) => err ? console.log(err) : null);
    } else {
        console.log('ALERT: No title provided.');
    }
    return response;
  })
  .then((response) => {
    if(response.license) {
        for(const i of licenses) {
            if(i.name == response.license) {
                fs.appendFile('./output/README.md', `${i.badge}\n`, (err) => err ? console.log(err) : null);
            }
        }
    }
    return response;
  })
  .then((response) => {
    if(response.desc) {
        fs.appendFile('./output/README.md', `## Description\n${response.desc}\n`, (err) => err ? console.log(err) : null);
    } else {
        console.log('ALERT: No description provided.');
    }
    return response;
  })

TL;DR我试着链接一些.then语句来让这段代码用特定的有序结构编写一个markdown文件,但是它仍然以不正确的、看似随机的顺序执行。

stszievb

stszievb1#

对于需要一个接一个执行的异步操作,在开始下一个操作之前,等待上一个操作完成的“通知”是很重要的。
您使用的fs方法是异步的,它们是callback based。为了简化操作,并且能够在.then函数中依赖它们-您需要promisifyexample)这些函数,并正确处理它们的返回承诺。
首选的方法是使用x1m3 n1 API,如this one,或fs sync api,如这个(不推荐,但无论如何,仍然是一个解决方案)。
示例:

const fs = require("fs");

// ...
.then(async (response) => {
  const filePath = "./output/README.md";
  await fs.promises.writeFile(filePath, "");
  if (response.title) {
    await fs.promises.appendFile(filePath, `# ${response.title}\n`);
  } else {
    console.log("ALERT: No title provided.");
  }
  if (response.license) {
    for (const i of licenses) {
      if (i.name === response.license) {
        await fs.promises.appendFile(filePath, `${i.badge}\n`);
      }
    }
  }
  if (response.desc) {
    await fs.promises.appendFile(
      filePath,
      `## Description\n${response.desc}\n`
    );
  } else {
    console.log("ALERT: No description provided.");
  }
  return response;
});
omvjsjqw

omvjsjqw2#

UPDATE:当然,当我求助于Stackoverflow时,我就回答了自己的问题。我的解决方案是简单地不链接多个.then语句,而是使用一个writeFile函数和一个很长的模板文字,所有这些都在一个.then语句中,来创建markdown文件。如下所示:

.then((response) => {
    let badge;
    let toc = '## Table of Contents\n1. [Installation](#installation)\n2. [Usage](#usage)\n3. [License](#license)\n4. [Contributors](#contributors)\n5. [Questions](#questions)';
    for(const i of licenses) {
        if(i.name == response.license) {
            badge = i.badge;
        }
    }
    fs.writeFile('./output/README.md',
        `# ${response.title}\n${badge}\n# Description\n${response.desc}\n${toc}\n# Installation\n${response.install}\n# Usage\n${response.usage}\n# License\n${response.license}\n# Contributors\n${response.contr}\n# Questions\nGitHub username: ${response.github}\nEmail address: ${response.email}`,
        (err) => err ? console.log(err) : null);
  })

这并没有解决为什么那些chained .thens不起作用的谜团,但事后看来,这是多余的。我可能必须修饰一下这段代码,以确保它不会产生错误,如果一个输入丢失,但它应该都适合在这一个语句。

相关问题