title: How to avoid Await.ready in Scala while using Futures?
body: <p>I have following pseudo code.
  Invoke <code>fetch</code>, <code>fetchRecordDetail</code>, <code>upload</code> and <code>notifyUploaded</code> functions in sequence. Each function returns a future event but the first functions returns Option[T], going forward(<code>fetchRecordDetail</code>, <code>upload</code> and <code>notifyUploaded</code>) calls I need to carry only Some[T] type and ignore None. </p>
  
  <p>Unfortunately I was able to achieve the following output with too many <code>Await.ready</code> calls.</p>
  
  <p><strong>Expected output</strong></p>
  
  <p>notified List(UploadResult(a_detail_uploaded), UploadResult(c_detail_uploaded))</p>
  
  <h2><strong>Code</strong></h2>
  
  <pre><code>def fetch(id: String): Future[Option[Record]] = Future {
      Thread sleep 100
      if (id != "b" &amp;&amp; id != "d") {
          Some(Record(id))
      } else None
  }
  
  def fetchRecordDetail(record: Record): Future[RecordDetail] = Future {
      Thread sleep 100
      RecordDetail(record.id + "_detail")
  }
  
  def upload(recordDetail: RecordDetail): Future[UploadResult] = Future {
      Thread sleep 100
      UploadResult(recordDetail.id + "_uploaded")
  }
  
  def notifyUploaded(results: Seq[UploadResult]): Future[Unit] = Future{ println("notified " + results)}
  
     val result: Future[Unit] = //Final call to 'notifyUploaded' goes here
  
      Await.ready(result, Duration.Inf)
  </code></pre>
  
  <p>Can someone help to improvise this code by avoiding <code>Await.ready</code> calls.</p>
  
  <pre><code>val ids: Seq[String] = Seq("a", "b", "c", "d")
  def filterSome(s:String) = fetch(s) map ((s, _)) collect { case (s, Some(v)) =&gt; v }
  val validData = ids map filterSome
  Await.ready(Future.sequence(validData), Duration.Inf)
  val records = validData.map(_.value.get.toOption)
  val recordDetails = records.flatten map fetchRecordDetail
  Await.ready(Future.sequence(recordDetails), Duration.Inf)
  val uploadResult = recordDetails.map(_.value.get.toOption).flatten  map upload
  Await.ready(Future.sequence(uploadResult), Duration.Inf)
  val seqUploadResult = uploadResult.map(_.value.get.toOption)
  val result: Future[Unit] =  notifyUploaded(seqUploadResult.flatten)
  Await.ready(result, Duration.Inf)
  </code></pre>