nodejs编写同步函数,例如fs.readFileSync

时间:2019-01-19 20:42:13

标签: javascript node.js synchronous

我想创建从数据库中获取数据的函数,例如executeQuery(sql)。但是我不希望从该函数返回任何承诺,也不想传递任何回调函数。我只想返回查询结果。

例如:

var rows = executeQuery('SELECT * FROM table');
console.log('database query completed:', rows);

我知道这不是javascript的工作方式。我也经历了许多也想要这个东西的stackoverflow问题。但是每个人都说没有办法。

现在这是我的问题,如果不可能的话,那么fs.readFileSync()之类的功能是如何工作的。这些函数既不需要任何回调,也不需要返回任何承诺。他们只是按照自己的定义去做。

4 个答案:

答案 0 :(得分:1)

更新:就像@Paulpro在评论中说的那样,下面的答案永远行不通,因为代码将陷入无限循环。所以你最好选择一个承诺


我建议像@ happy-machine和@bergur一样,最好使用Promises。但是如果您想了解fs.readFileSync()的工作原理,请阅读fs module code in nodejs source code

您会发现它执行了do {} while(),并且您可以执行相同的操作 像这样同步您的异步代码

var rows;
executeQuery('SELECT * FROM table').then(
  promiseResponse => {
   rows = promiseResponse
  }
)
do {
  // nothing
} while(!rows) // rows is undefined
console.log('database query completed:', rows);

答案 1 :(得分:0)

fs.readFileSync()可以同步,因为它仅与本地文件系统一起使用,这可能是一个快速操作。如果您的数据库是本地数据库,则可以想象它也被编写为同步数据库。但是,如果您的数据库在线,则executeQuery将必须发送http请求并等待响应,这可能需要很长时间,并且由于以下原因可能无法同步执行:

注意:从Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)开始,由于对用户体验的负面影响,主线程上的同步请求已被弃用。

答案 2 :(得分:-1)

您可以使用异步/等待。这将为您提供与readFileSync几乎相同的语法-这不是承诺链或回调。

var rows = await executeQuery('SELECT * FROM table')
console.log('database query completed:', rows) // this now works

您只需要将其包装在异步函数中即可。

只是为了避免造成混乱。该函数仍然是异步的,它只是语法糖,使读取代码更容易。

答案 3 :(得分:-2)

同步是同步的,并阻止执行直到完成。 fs的Sync方法将其结果作为返回值返回。

其他fs非同步方法是异步的,当它们在后台运行时会立即返回。您传递一个回调函数,当它们完成时将被调用。

当您开始使用Javascript时,承诺会有些噩梦,但是由于Javascript只有一个线程,一旦您习惯了它们,它们就成为Javascript的一部分。如果使用Sync函数,则阻塞线程通常不是一个好主意,尤其是在不使用worker的情况下。

我写了一篇文章,关于如果您想在这里查看,请把您的承诺包裹住

Why Does Async Always Return a Promise?