【问题标题】:How we can guarantee synchronous behaviour in Javascript when we need it?我们如何在需要时保证 Javascript 中的同步行为?
【发布时间】:2021-05-13 23:51:29
【问题描述】:

我是 Javascript 编程的新手,这是一个有些人为的例子,但它是我遇到的许多问题的核心,我需要在 javascript 中同步排序一些处理。

假设我有两个文本文件 Sample1.text 其中包含

line number 1
line number 2
line number 3
line number 4
line number 5
line number 6
line number 7

以及包含的Sample2.txt

line number 8
line number 9
line number 10
line number 11
line number 12
line number 13
line number 14

我需要处理它们,以便 Sample1.txt 始终在 Sample2.txt 之前完成处理

这是我的代码:

const fs = require("fs");
const { mainModule } = require("process");
// const readline = require("readline");

const readline = require("readline-promise").default;

const rlp2 = readline.createInterface({
  terminal: false,
  input: fs.createReadStream("sample2.txt"),
});

const rlp1 = readline.createInterface({
  terminal: false,
  input: fs.createReadStream("sample1.txt"),
});

// No top-level await in JS yet, so we put it in an async function
async function processLineByLine_1_7() {
  for await (const line of rlp2) console.log(`Read this line: ${line}`);
}

// No top-level await in JS yet, so we put it in an async function
async function processLineByLine_8_14() {
  for await (const line of rlp1) {
    console.log(`Read this line: ${line}`);
  }
}

processLineByLine_1_7();
processLineByLine_8_14();

还有输出:

Read this line: line number 8
Read this line: line number 9
Read this line: line number 10
Read this line: line number 11
Read this line: line number 12
Read this line: line number 13
Read this line: line number 1
Read this line: line number 2
Read this line: line number 3
Read this line: line number 4
Read this line: line number 5
Read this line: line number 6
Read this line: line number 7
Read this line: line number 14

我如何保证订单?以便我始终保证订单,以便我始终得到:

Read this line: line number 1
Read this line: line number 2
Read this line: line number 3
Read this line: line number 4
Read this line: line number 5
Read this line: line number 6
Read this line: line number 7
Read this line: line number 8
Read this line: line number 9
Read this line: line number 10
Read this line: line number 11
Read this line: line number 12
Read this line: line number 13
Read this line: line number 14

我试图了解我们如何在需要时保证同步行为。 是否可以使用 for await 构造将函数 processLineByLine_1_7 包装在 promise 中,还是有其他方法?

如果我试试这个:

async function main() {

  await processLineByLine_1_7();
  await processLineByLine_8_14();
}

main();

我看到以下输出:

> node .

Read this line: line number 8
Read this line: line number 9
Read this line: line number 10
Read this line: line number 11
Read this line: line number 12
Read this line: line number 13
Read this line: line number 14

【问题讨论】:

  • await processLineByLine_1_7();await processLineByLine_8_14(); ???
  • 感谢 Keith,但 await 仅在异步函数和模块的顶层主体中有效。我也相信 processLineByLine_1_7() 需要返回一个承诺。
  • 是的,所以你把它放在一个 async 函数中并运行它.. processLineByLine_1_7() 返回一个 Promise。
  • async function main() { //if (isPromise(processLineByLine_1_7)) console.log("Returns a promise");等待 processLineByLine_1_7();等待 processLineByLine_8_14(); } 主要的();输出 > 节点。 ` 阅读此行:第 8 行 阅读此行:第 9 行 阅读此行:第 10 行 阅读此行:第 11 行 阅读此行:第 12 行 阅读此行:第 13 行 阅读此行:第 14 行`
  • 请注意,您在1_7 中使用rlp2,在8_14 中使用rlp1。我想这是一个错字?!

标签: javascript node.js asynchronous es6-promise synchronous


【解决方案1】:

我认为问题在于您的 readline 接口 已经开始处理,因此顺序混淆了。尝试仅在实际需要时创建它们,例如:

const fs = require("fs");
const readline = require("readline-promise").default;

async function processLineByLine_1_7() {
  const rl = readline.createInterface({
    input: fs.createReadStream("sample1.txt"),
  });

  for await (const line of rl) {
    console.log(`Read this line: ${line}`);
  }
}

async function processLineByLine_8_14() {
  const rl = readline.createInterface({
    input: fs.createReadStream("sample2.txt"),
  });

  for await (const line of rl) {
    console.log(`Read this line: ${line}`);
  }
}

(async () => {
  await processLineByLine_1_7();
  await processLineByLine_8_14();
})();

注意:显然这可以重构为“更干”

【讨论】:

  • 谢谢 Yoshi,是的,问题出在接口上。我将它们移到函数中,从而解决了问题。所以我猜最初的困惑是我是否可以像 Keith 和 Prime 指出的那样等待 processLineByLine 函数。
  • 奇怪!!,如果这确实是解决方案的一部分,则将 createInterface 放入函数中。这意味着async generator 正在消耗一些空虚……奇怪!!……
  • @Keith 我也很惊讶,不会有这样的行为。我的猜测是,在等待的任何东西之外创建接口,让它做承诺做的事情。
【解决方案2】:

您需要在processLineByLine_1_7processLineByLine_8_14前面附加await

await processLineByLine_1_7();
await processLineByLine_8_14();

【讨论】:

    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多