◆ then は後回しになるけど setTimeout より先に実行される
◆ then のチェーンや then の中で then を呼び出してもすべて setTimeout より先になる
◆ setImmediate が作れる 

new Promise(e => console.log(1))
console.log(2)

を実行すると
1
2

と表示されます
Promise のコンストラクタに渡す関数は即実行されます

では then をつけてみます
new Promise(resolve => {
    console.log(1)
    resolve()
}).then(e => console.log(3))
console.log(2)
1
2
3

特に Promise のコンストラクタに渡して関数で非同期処理をしてるわけでもないのに then の関数が呼ばれるより先に console.log(2) が評価されています

この実行順には注意しないといけないです
new Promise(_ => console.log(1))
Promise.resolve().then(_ => console.log(1))

同じような意味で使っていたり コンストラクタだけ書き方特殊なのが嫌で then に統一したいからと下を進める人もいます

ですが 実行タイミングが別なので これは完全に別物です
そのときそのときで適してる方を使うべきで常にこっちと決めるべきではないです



ではここからが本題です

then で後回しになるのは内部で setTimeout 0 が実行されてるのでしょうか?

こんなコードを動かしてみます
setTimeout(_ => console.log(1), 0)
Promise.resolve().then(_ => console.log(2))
2
Promise {  }
1

2 の then が先に実行されていますね
それと 間にある Promise {} は REPL の返り値結果です
つまり REPL に打ったコードが評価されて完全に終わって 結果が出力される前に then で登録したものが解決されます
setTimeout は完全に JavaScript でのひとつのまとまりの処理が終わって REPL の結果が出た後に処理されます


ちょっと長い例
setTimeout(_ => console.log(1), 0)
Promise.resolve().then(_ => console.log(2))

setTimeout(_ => console.log(3), 0)
Promise.resolve().then(_ => console.log(4))

setTimeout(_ => console.log(5), 0)
Promise.resolve().then(_ => console.log(6))

Promise.resolve()
    .then(_ => console.log(11))
    .then(_ => console.log(12))
    .then(_ => console.log(13))
    .then(_ => console.log(14))
    .then(_ => console.log(15))

Promise.resolve()
    .then(_ => {
        console.log(21)
        setTimeout(_ => console.log(210), 0)
    })
    .then(_ => {
        console.log(22)
        setTimeout(_ => console.log(220), 0)
    })
    .then(_ => {
        console.log(23)
        setTimeout(_ => console.log(230), 0)
    })
    .then(_ => {
        console.log(24)
        setTimeout(_ => console.log(240), 0)
    })
    .then(_ => {
        console.log(25)
        setTimeout(_ => console.log(250), 0)
    })

setTimeout(_ => {
    console.log(30)
    Promise.resolve().then(_ => console.log(300))
}, 0)

console.log(1000)
1000
2
4
6
11
21
12
22
13
23
14
24
15
25
undefined
1
3
5
30
300
210
220
230
240
250

undefined が REPL の結果です
11,21,12,22,... と交互に並んでいて then のチェーン数が同じものは同じタイミングで登録が早いほうが先になっています

また setTimeout 内で then をしたほうが then の中で setTimeout するより先に実行されます

Firefox でも同じ順になるので then の実行タイミングはちゃんと決められているようです


setTimeout より早く実行されて いま実行されてる JavaScript のまとまりが終わった直後に実行というと setImmediate っぽいですよね
!function(){
    var id_counter = 1
    var canceler = {}

    function setImmediate(fn, ...args){
        var canceled = false
        var iid = id_counter++
        Promise.resolve().then(e => {
            if(!canceled) fn(...args)
            delete canceler[iid]
        })
        canceler[iid] = _ => canceled = true
        return iid
    }
    function clearImmediate(iid){
        canceler[iid]()
    }

    window.setImmediate = setImmediate
    window.clearImmediate = clearImmediate
}()

これで setImmediate が使えます
setImmediate の中で setImmediate を繰り返しても setTimeout 0 より先に全部実行されます
setImmediate(_ => console.log(1))
console.log(2)
2
1
var iid = setImmediate(1)
console.log(2)
clearImmediate(iid)
2
setImmediate(_ => {
    console.log(1)
    setImmediate(_ => {
        console.log(2)
        setImmediate(_ => {
            console.log(3)
            setImmediate(_ => {
                console.log(4)
            })
        })
    })
})
setTimeout(_ => console.log(10))
1
2
3
4
10