Use callback to avoid setTimeout