То, что вы действительно хотите, это чтобы callback
принял собственный обратный вызов. (Я знаю, что вы сказали, что это черный ящик, но это должен быть другой черный ящик.) Затем, вместо ожидания обратного вызова, вы просто передаете ему продолжение и callback
отвечает за присвоение этого продолжение обработчика завершения анимации (или чего бы то ни было). Так что вместо:
doSomeStuff();
runner(callback);
doMoreStuff();
хочешь
doSomeStuff();
callback.call(doMoreStuff);
Вот ответ на связанный вопрос. В более общем смысле, этот шаблон стиль передачи продолжения и является центральным в том, как jQuery обрабатывает вещи.