I faced the same issue recently. I found a solution that apparently works for all devices. You can't do async focus programmatically but you can switch focus to your target input when some other input is already focused. So what you need to do is create, hide, append to DOM & focus a fake input on trigger event and, when the async action completes, just call focus again on the target input. Here's an example snippet - run it on your mobile.
edit:
Here's a fiddle with the same code. Apparently you can't run attached snippets on mobiles (or I'm doing something wrong).
var $triggerCheckbox = $("#trigger-checkbox");_x000D_
var $targetInput = $("#target-input");_x000D_
_x000D_
// Create fake & invisible input_x000D_
var $fakeInput = $("<input type='text' />")_x000D_
.css({_x000D_
position: "absolute",_x000D_
width: $targetInput.outerWidth(), // zoom properly (iOS)_x000D_
height: 0, // hide cursor (font-size: 0 will zoom to quarks level) (iOS)_x000D_
opacity: 0, // make input transparent :]_x000D_
});_x000D_
_x000D_
var delay = 2000; // That's crazy long, but good as an example_x000D_
_x000D_
$triggerCheckbox.on("change", function(event) {_x000D_
// Disable input when unchecking trigger checkbox (presentational purpose)_x000D_
if (!event.target.checked) {_x000D_
return $targetInput_x000D_
.attr("disabled", true)_x000D_
.attr("placeholder", "I'm disabled");_x000D_
}_x000D_
_x000D_
// Prepend to target input container and focus fake input_x000D_
$fakeInput.prependTo("#container").focus();_x000D_
_x000D_
// Update placeholder (presentational purpose)_x000D_
$targetInput.attr("placeholder", "Wait for it...");_x000D_
_x000D_
// setTimeout, fetch or any async action will work_x000D_
setTimeout(function() {_x000D_
_x000D_
// Shift focus to target input_x000D_
$targetInput_x000D_
.attr("disabled", false)_x000D_
.attr("placeholder", "I'm alive!")_x000D_
.focus();_x000D_
_x000D_
// Remove fake input - no need to keep it in DOM_x000D_
$fakeInput.remove();_x000D_
}, delay);_x000D_
});
_x000D_
label {_x000D_
display: block;_x000D_
margin-top: 20px;_x000D_
}_x000D_
_x000D_
input {_x000D_
box-sizing: border-box;_x000D_
font-size: inherit;_x000D_
}_x000D_
_x000D_
#container {_x000D_
position: relative;_x000D_
}_x000D_
_x000D_
#target-input {_x000D_
width: 250px;_x000D_
padding: 10px;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>_x000D_
<div id="container">_x000D_
<input type="text" id="target-input" placeholder="I'm disabled" />_x000D_
_x000D_
<label>_x000D_
<input type="checkbox" id="trigger-checkbox" />_x000D_
focus with setTimetout_x000D_
</label>_x000D_
</div>
_x000D_