Skip to content

Race condition when chaining a promise after being fulfilled? #72

Description

@DNCGraef

Hi @khanlou - first of all, thanks for all the effort putting this library together!

I've come across a potential issue which seems like a race condition inside the library. Here is code for a test:

class PromiseTests: XCTestCase {
    
    func testChainingOntoFulfilledPromiseWithOutstandingCallbacks() {
        let promise = Promise<String>()
        var didCallAlways = false
        let thenExpectation = expectation(description: "Did call 'then'")
        let alwaysExpectation = expectation(description: "Did call 'always'")
        
        promise.catch { error in
            XCTAssertEqual(didCallAlways, false)
        }.then { value in
            XCTAssertEqual(didCallAlways, false)
            thenExpectation.fulfill()
        }
        
        promise.fulfill("Hello World")
        promise.always {
            didCallAlways = true
            alwaysExpectation.fulfill()
        }
        
        wait(for: [thenExpectation, alwaysExpectation])
    }
    
}

Which intermittently fails inside

.then { value in
            XCTAssertEqual(didCallAlways, false)
            thenExpectation.fulfill()
        }

on

XCTAssertEqual(didCallAlways, false)

So, the scenario here is chaining something to the end of a fulfilled promise which has outstanding tasks chained on the end. From what I can understand stepping through the source code, I think the order in which the the "catch" & "then" tasks vs the "always" task executes is not guaranteed.

My assumption in this case was that the "always" should be queued behind the outstanding "catch" and "then" tasks.

I'm not sure if you'd consider this a bug, or a misuse of the API or something else, so thought I would raise it for discussion

Cheers

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions