The solution I've often employed in this type of scenario makes use of cfthread and some form of async polling.
Without a concrete example, I'll try and outline the basic mechanics...
User submits request.
A Unique ID is generated.
A <cfthread> begins, handling the long-running request and writing status update to a session variable scoped by the Unique ID.
The Unique Id is returned to the user, and they are directed to a page that uses JS to poll some endpoint that will read the session-scoped status information.
I've used XHR polling, and event-stream based solutions here - but the principle holds whichever technique you employ.