nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
106.76k stars 29.13k forks source link

Built-in low-cost async to sync method #34918

Closed septs closed 4 years ago

septs commented 4 years ago

reduce unstable conditions caused by such hacking https://npm.im/deasync

import { deasync, depromise } from "util";

const sleepWithSync = deasync((timeout, done) => { setTimeout(done, timeout) });
const promiseWithSync = depromise(async (input) => input)

sleepWithSync(1000)
promiseWithSync(1) == 1
// sync done
bnoordhuis commented 4 years ago

reduce unstable conditions caused by such hacking

Unclear description. What are you asking or saying?

devsnek commented 4 years ago

Looks like a duplicate of #30634

oussematn commented 4 years ago

please review your question

jasnell commented 4 years ago

Given the way that Promises and async operations work within JavaScript and Node.js, converting those into sync blocking operations is not actually possible. The blocking to wait for completion would block the actual completion because the task queues would never be drained and the event loop would never turn to allow the Async ops to complete. There are ways you can come close to what you want using Worker threads but at a fairly steep performance and complexity price.

If you believe there's a way to accomplish it in a reasonable way, pull requests are always welcome.

sindresorhus commented 4 years ago

Given the way that Promises and async operations work within JavaScript and Node.js, converting those into sync blocking operations is not actually possible.

How is desync able to do it then?

sindresorhus commented 4 years ago

Sidenote: If you just need sleep synchronously for a certain amount of time, this can now be achieved in pure JS: https://github.com/sindresorhus/sleep-synchronously/blob/1fe452b47e810cf21bbc67e022a70ab925603759/index.js#L4

devsnek commented 4 years ago

From the dupe issue:

I should've been a bit clearer. It's not possible to take an arbitrary function that performs some unknown async behaviour and make it synchronous. deasync exploits the fact that the majority of async behaviour in node applications is very similar: one-shot calls to libuv apis. However, as with the bug you linked, not everything follows that pattern.

Node is able to provide sync apis because it has specialized C++ code for those individual synchronous apis. We don't have an internal magic "syncify" api that could be exposed.

devsnek commented 4 years ago

Since this is a dupe, closing out.