If I have the following :
var deferred = Q.defer();
deferred.resolve();
var a = deferred.promise.then(function() {
console.log(1);
});
console.log
Answer is consistency.
In real code, you don't have promises that are always immediately resolved when created, they would be pointless. So you have promises that sometimes may be immediately resolved.
In that case, you don't want to have a different flow. You want always the same, predictable flow. So you want the next function to be always called on next tick.
Don't use a promise when you don't need one.
It's a design mistake based on a set of opinions and assumptions. It has become latched because it was rushed out without full technical verification in a design by committee process that also had the back pressure of a lot of vendors implementing their own already with the same mistake making it hard to backtrack.
Once a standard goes out for JS to the web it can be revoked, even if it's broken with the idea being that webpages shouldn't break. If someone wrote a page today, then died, it should be possible to still view it in your browser in five years. It would be very problematic if when browsing the web you kept bumping into pages that didn't work with your browser.
In very simple use cases it doesn't do much harm and removes confusion about whether something is maybe async.
For increasingly non-trivial use cases it causes increasingly more harm and adds confusion. Initially it appears to make it easier to reason about your code but it sacrifices the less trivial usage for the least trivial usage.
It's overall much easier to reason about your code if it doesn't run things in the next tick that don't need to be async at all. This is a case of choosing to damage the language at level two to cater to level one users, at the expense of level two users and above, rather than working to help ascend level one users to level two users. It's a condescending or pessimistic design decision.
There's an intermediate solution where it's possible to run each task as if it runs after the current code runs to completion but things are scheduled in the correct order. This hasn't been implemented and it's also debatable as compromises don't always produce the best solutions. This compromise produces performance issues for direct return callstacks.
The way promises work means that the forward callstack is depth first and run to completion (isolated) but the return callstack is breadth first and run in pieces interleaved with other return callstacks. These are two radically different concept and behaviours. Traditionally with callbacks both run in the same way.
It also means you can't naively replace callbacks with promises or anything based on promises. Callbacks give you more options which promises take away. If you replace callbacks with promises without taking this difference into account you can create code that has stability issues and potential security issues as well since this behaviour of unordering events can cause the current code flow to unexpectedly jump track.
You can't rely on order which means there are cases with promises where if you ask for lots of things when you get them back you have to double check they're the thing you asked for where as you would not need to do this with callbacks. You may also need to buffer and reorder events which you would not need to do with callbacks. It can make benchmarks unreliable as well if you're not careful to isolate the two things being run.
This can also create serious performance bottlenecks that you can't always easily prevent. If you use promises a hundred returned results returned at once from a single event to an iterator, each taking one second per return call and their promise resolve depth is two, they'll all be broken into half with the first halves all run then the second halves. That means it will take 50.5 seconds before anything can finish where as with callbacks after 50 seconds half of them would already be finished. If the result of the task is passed along to another external service for processing then it leaves that service standing idle for 50 seconds when it could have been processing your results. This makes the promises terrible for when you want both low latency and high throughput under services that take load demonstrating the weakness of the design.
Not being able to naively replace callbacks with promises is one of the most devastating consequences of this design mistake which is also carried over to async/await. If you want to convert a callback library you can't simple change the syntax, you must carefully scrutinise the semantics at every point.
There is no plan to fix this. You can create your own promises and generators can be used to provide the same kind of syntax as async/await but with the same predictable and high performance behaviour of callbacks. You may however have problems playing nice with other libraries that still rely on native promises.