Оператор do никак не влияет на последовательность, вы просто "вклиниваетесь" в нее, получаете ее текущие данные и можете запустить какие-либо side effects на основании этих данных (результат выполнения функции в do никак не влияет на данные, которые окажутся в следующем операторе, либо конечной подписке). На сам таймер вы подписаны после оператора do, поэтому сначала выполнятся действия в do, затем в subscribe.
Точно также любое действие выполнится в любом другом операторе до того, как вы попадете в subscribe, но другие операторы так или иначе меняют исходную последовательность.
Чтобы добиться нужного вам поведения, можете записать последовательность в переменную и подписаться на нее 2 раза в нужном порядке:
const obs = Observable.timer(0, 3000);
obs.subscribe(i => console.log(i));
obs.subscribe(i => console.log('tick', i));