deasync icon indicating copy to clipboard operation
deasync copied to clipboard

Embedded Promise not Resolving

Open Matchlighter opened this issue 3 years ago • 6 comments

I've been building a CLI tool and have needed to make use an async library within synchronous functions. I've encountered an issue where deasync will lock up when the result is dependent on a Promise resolving. It works fine with Node 10, but not with 12 or 14. I've managed to come up with this minimal reproducing code:

console.log(0)
function asyncfunc(cb) {
    console.log(1)
    new Promise((resolve) => {
        console.log(2);
        resolve(4)
    }).then((v) => {
        console.log(4)
        cb();
    })
    console.log(3);
}
deasync(asyncfunc)()
console.log(5)

// On Node 12 and 14, prints:
// > 0
// > 1
// > 2
// > 3

I originally discovered this using https://github.com/Yukaii/synchronized-promise/blob/master/lib/index.js, which has some timeout logic. When using that the output is:

> 0
> 1
> 2
> 3
(frozen until timeout)
> 4
> Error:  called timeout

Possibly duplicate of #136 and/or #138.

Matchlighter avatar Dec 04 '20 04:12 Matchlighter

I'm having the same problem, is there any way to solve this or is there a fix already?

victorreinor avatar Feb 16 '22 18:02 victorreinor

Same issue. I have to call synchronous code inside a handler for a webserver which is asynchronous. The synchronous part needs to call an external service where the client library is async-only. I tried using deasync on that client library, and ran into this issue.

acarl005 avatar Mar 10 '22 19:03 acarl005

+1

vbgm avatar Feb 18 '23 15:02 vbgm

+1

tiitremmel avatar Mar 15 '23 10:03 tiitremmel

Avoid this library if there is any good chance to do so. Or if you are not 100% sure how it works. Otherwise, you can easily get your code in deadlock.

jardicc avatar Mar 15 '23 11:03 jardicc

try this

const deasync = require('deasync');

deasync.promise = function(fn) {
	return function () {
		var done = false
		var args = Array.prototype.slice.apply(arguments)
		var err
		var res

        fn.apply(this, args).then(resolve).catch(reject);

		deasync.loopWhile(function () {
			return !done
		})
		if (err)
			throw err

		return res
		function resolve(r) {
			res = r
			done = true
		}

		function reject(e) {
			err = e
			done = true
		}
	}
};

const readFilePromiseSync = deasync.promise(require('fs').promises.readFile);
const buffer = readFilePromiseSync(__filename);
console.log({buffer});

jonathan-annett avatar Jan 22 '24 11:01 jonathan-annett