Я изменил вашу функцию fetchingFunction, чтобы она возвращала обещание, поэтому он будет действовать так, как если бы вы выполняли там асинхронный вызов.
Сначала вы вызываете fetchingFunction (), которая возвращает обещание.
Во-вторых, вы добавляете обратный вызов к этому обещанию, чтобы оно выполнялось после того, как обещание выполнено, принимая возвращенное значение.
var loopControl = 0;
$('[data-toggle=tab]').on('show.bs.tab', function(e) {
if (loopControl != 0) return;
loopControl = 1;
e.preventDefault();
var ref = this.href.replace('#', '');
fetchingFunction().then(function(url){
console.log(url);
$.ajax({
url: url,
complete: function() {
fakeFunction2();
//$('.' + ref + '_tab').click();
loopControl = 0; //processing is done, reset the lock
}
});
});
});
function fetchingFunction() {
return new Promise(function(resolve, reject){
setTimeout(function() {
console.log("1");
resolve('https://stackoverflow.com/');
}, 2000);
});
}
function fakeFunction2() {
console.log("2");
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<ul class="nav nav-tabs">
<li><a class='aaa_tab' href="#aaa" data-toggle="tab">AAA</a></li>
<li><a class='bbb_tab' href="#bbb" data-toggle="tab">BBB</a></li>
<li><a class='ccc_tab' href="#ccc" data-toggle="tab">CCC</a></li>
</ul>
<div class="tab-content" id="tabs">
<div class="tab-pane" id="aaa">...Content1...</div>
<div class="tab-pane" id="bbb">...Content2...</div>
<div class="tab-pane" id="ccc">...Content3...</div>
</div>