young-steveo / bottlejs

A powerful dependency injection micro container for JavaScript applications
MIT License
1.29k stars 67 forks source link

Provide an async defer functionality #139

Closed buckelieg closed 4 years ago

buckelieg commented 4 years ago

It could be great to have middleware-like functionality with defer-resolve pattern. I.e. I want to have "next" option in deferred function to make call it inside Promise.resolve()

young-steveo commented 4 years ago

That's a cool idea, so something like:

const bottle = Bottle.pop();
bottle.defer(function(foo) {
    console.log(foo + ' sync');
});

bottle.deferAsync(function(foo, next) {
    setTimeout(function() {
        console.log(foo + ' async');
        next();
    }, 1);
});

bottle.resolve('test');
buckelieg commented 4 years ago

Yes, something like that. My general aim is to use BottleJS in conjunction with HeadJS so that I can bind resources loading with complex component object creation inside the Container. That is like lazy loading online dependency management system. And I can initialize some parts of app instantly when resources are ready.

young-steveo commented 4 years ago

Thank you for the suggestion!

The more I think about it, the more I am inclined to keep async apis outside of bottle. There was a similar idea a few years ago for an async service: https://github.com/young-steveo/bottlejs/issues/40#issue-120213323 . The comment thread on that issue is relevant to this issue.

One of the design goals for bottle is to stay functional, yet small and lightweight. I think I want to avoid adding promise or async code to the core.

It is possible to solve the proposed problem without adding functionality to bottlejs; just invert the order of operations. Instead of having bottle resolve things async for you, perform the async opration, then call bottle.resolve in the async callback.