我想创建从数据库中获取数据的函数,例如executeQuery(sql)
。但是我不希望从该函数返回任何承诺,也不想传递任何回调函数。我只想返回查询结果。
例如:
var rows = executeQuery('SELECT * FROM table');
console.log('database query completed:', rows);
我知道这不是javascript的工作方式。我也经历了许多也想要这个东西的stackoverflow问题。但是每个人都说没有办法。
现在这是我的问题,如果不可能的话,那么fs.readFileSync()
之类的功能是如何工作的。这些函数既不需要任何回调,也不需要返回任何承诺。他们只是按照自己的定义去做。
答案 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的情况下。
我写了一篇文章,关于如果您想在这里查看,请把您的承诺包裹住