google / promises

Promises is a modern framework that provides a synchronization construct for Swift and Objective-C.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Syntax error when attempting to do work in .then{} prior to executing next Promise function

heloguy opened this issue · comments

commented
getEventsFromDatabase(for: today)
      .then { data in
       // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

The above code works as advertised in the documentation.

getEventsFromDatabase(for: today)
      .then { data in
        self.progress.progress = 0.2 // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

In the first closure I add a block of code to update the UIProgressView.

Syntax error: Missing return in a closure expected to return 'Promise'

A look at the individual function differences:

1

private func getEventsFromDatabase(for date: Date) -> Promise<[NonCodableEvent]> {
    return Promise {
      return try DatabaseController.getEventsForDate(date: date, container: self.persistentContainer)
    }
  }

2

  private func getEventsFromNetwork(for date: Date, event: [NonCodableEvent]) -> Promise<Any> {
    if(event.count > 0) {
      return Promise(on: .global()) { () -> [NonCodableEvent] in
        return event
      }
    }
    
    return Promise(on: .global()) { () -> Any in
      let (data, response, error) = ServiceLayer().request(route: NavyRoute(squadron: Squadron.ht8, date: date))
      if let error = error {
        throw error
      }
      
      //TODO: Handle response code issues
      
      return data
    }
  }

In '1', I'm returning a "generic" promise on the .main thread.
In '2', I'm returning a Promise explicitly run on the .global thread.

Trying to wrap my head around why this might be causing issues, or if there's something else I'm missing.

I think the confusion may be from swift automatically returning the value of a single line block. Once you add a second line that no longer happens.

Starting with your first block:

getEventsFromDatabase(for: today)
      .then { data in
      // Then block 1
       // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
      // Then block 2
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
      // Then block 3
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

In then block 1, the Promise from the call to self.getEventsFromNetwork is returned. But in then block 2, the return type of the then block is Void. Same with block 3.

So block 2 will get the result data from self.getEventsFromNetwork, but block 3 will also get those same results because block 2 has no return value.

Once you add the second line in the first block, all of the blocks now get the initial result from getEventsFromDatabase.

First thing I would try is adding explicit return statements.