首页 > 解决方案 > 订单丢失(Javascript 和 Node.js)

问题描述

我正在尝试做一个自动视频创建系统并且有一个主要问题。问题在这里消失了。程序正常运行,但输出的打印顺序不正确。

    let fullPath = "script.txt"
fs.readFile(fullPath, 'UTF-8', async (err, data) => {
    if (err) {
        console.error("READSCRIPTERROR: " + err);
        return
    }
    let lines = data.split(/\r?\n/)
    lines.forEach(async line => {

        let res = await findimage(line)

        let filename = Math.floor(Math.random() * 10000).toString();
        txtomp3.getMp3(replaceall("**", "", line)).then(async function (binaryStream) {
            let file = fs.createWriteStream("./voice/" + filename + ".mp3");
            file.write(binaryStream);
            file.end();
            voices.push("./voice/" + filename + ".mp3")
            getAudioDurationInSeconds("./voice/" + filename + ".mp3").then((duration) => {
                let dur = duration.toString().split(".")[0]
                console.log("Line" + line);
                mainImage(dur, line, filename, res)
            });
        })


    })


})

其他一切都在工作,但我只是没有让它工作。

在我的文件中是

你好1 你好2 你好3

但在那之后它就像随机

系统正在打印Test1 Hello Test2

虽然它应该以正确的顺序打印,即Hello Test1 Test2

标签: javascriptnode.js

解决方案


发生这种情况是因为 aforEach.then()call 都不会阻止下一个语句/迭代同步执行。

一个好的经验法则是:

  • 不要将async函数作为forEach回调传递;改用for循环。
  • 不要混合使用async.then()。选择一种模式并坚持下去

以下是简化异步的方法:

let fullPath = "script.txt"
fs.readFile(fullPath, 'UTF-8', async (err, data) => {
    if (err) {
        console.error("READSCRIPTERROR: " + err);
        return;
    }
    let lines = data.split(/\r?\n/);
    for (let line of lines) {
        let res = await findimage(line);
        let filename = Math.floor(Math.random() * 10000).toString();
        let binaryStream = await txtomp3.getMp3(replaceall("**", "", line));
        let file = fs.createWriteStream("./voice/" + filename + ".mp3");
        file.write(binaryStream);
        file.end();
        voices.push("./voice/" + filename + ".mp3");
        let duration = await getAudioDurationInSeconds("./voice/" + filename + ".mp3");
        let dur = duration.toString().split(".")[0];
        console.log("Line" + line);
        mainImage(dur, line, filename, res);        
    }
});

这假设您未提供的功能按预期工作。例如,如果mainImage是一个具有异步行为并返回承诺的函数,那么您也应该使用await它。


推荐阅读