如何使异步功能在Node.js中作为同步运行

时间:2019-08-20 17:59:23

标签: node.js

因此,我正在使用enquirer,并且我正在使用的所有功能都是aysncronus,但我希望它们是同步的。

const { Confirm } = require('enquirer');
const glob = require('glob');
const fs = require('fs');

//files1 is an array of files.
files1.forEach(file => {
    const filePrompt = new Confirm({
        name: 'file',
        message: `Would you like to add this to the concatenation list: ${file}?`
    });

    filePrompt.run().then(answer => {
        if (answer) {
             try {
                  fs.appendFileSync('tmp.txt', `file '${file}'`);
             } catch (err) {
                  console.error(err);
                  process.exit(1);
             }
         }
    }).catch(console.error);
});

最后,如果用户对要添加的文件说是,它将被追加到文件中。我需要该功能同步运行,以便在下一个提示开始之前完成该功能。

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

您尝试使用异步等待吗?

您可以在https://www.geeksforgeeks.org/using-async-await-in-node-js/

处查看一些示例。

答案 1 :(得分:0)

您可以将下一个提示放入try块中,它会同步运行,因为它必须等待第一个提示完成(成功)。但是这样做很快会使您在代码中陷入可怕的回调地狱。

根据您使用的库,Confirm对象继承Prompt对象,该对象将您的run()函数实现为Promise:https://github.com/enquirer/enquirer/blob/master/lib/prompt.js#L229

因此,在您的情况下,最好使用异步/等待。如果我正确键入了所有内容,则您的代码最后应如下所示:

const { Confirm } = require('enquirer');
const glob = require('glob');
const fs = require('fs');

//files1 is an array of files.
files1.forEach(async file => {
    try {
        const filePrompt = new Confirm({
            name: 'file',
            message: `Would you like to add this to the concatenation list: ${file}?`
        });

        const answer = await filePrompt.run();
        if (answer) {
            fs.appendFileSync('tmp.txt', `file '${file}'`);

            // ... your second prompt's logic here
        }
    } catch(error) {
        console.log(error);
        process.exit(1);
    }
});

答案 2 :(得分:0)

您需要的是 async / await ,以使您的异步功能等待下一次迭代。另外async / await不适用于forEach,因此您可能需要将 forEach 更改为 for..of 循环。

const { Confirm } = require('enquirer');
const glob = require('glob');
const fs = require('fs');

(async () => {
    try {
        for (let file of files1) {
            const filePrompt = new Confirm({
                name: 'file',
                message: `Would you like to add this to the concatenation list: ${file}?`
            });
            const answer = await filePrompt.run();
            if (answer) {
                fs.appendFileSync('tmp.txt', `file '${file}'`);
            }
        }
    } catch (err) {
        console.log(error);
        process.exit(1);
    }
})();

我将代码包装在 iife 函数中,因为await仅在内部和异步函数中起作用。

您可以使用循环和更多here

检查async / await实现

要了解有关 iife 的更多信息,请参阅this

p.s:无法获得测试代码的机会,因此可能需要进行一些修改。

希望这会有所帮助:)