diff --git a/lib/init.lua b/lib/init.lua index 21af89e..850951f 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -1221,7 +1221,7 @@ function Promise.prototype:_resolve(...) -- We assume that these callbacks will not throw errors. for _, callback in ipairs(self._queuedResolve) do - callback(...) + coroutine.wrap(callback)(...) end self:_finalize() @@ -1239,7 +1239,7 @@ function Promise.prototype:_reject(...) if not isEmpty(self._queuedReject) then -- We assume that these callbacks will not throw errors. for _, callback in ipairs(self._queuedReject) do - callback(...) + coroutine.wrap(callback)(...) end else -- At this point, no one was able to observe the error. @@ -1286,7 +1286,7 @@ function Promise.prototype:_finalize() -- Purposefully not passing values to callbacks here, as it could be the -- resolved values, or rejected errors. If the developer needs the values, -- they should use :andThen or :catch explicitly. - callback(self._status) + coroutine.wrap(callback)(self._status) end -- Clear references to other Promises to allow gc diff --git a/lib/init.spec.lua b/lib/init.spec.lua index 6780d15..096e4a9 100644 --- a/lib/init.spec.lua +++ b/lib/init.spec.lua @@ -261,6 +261,30 @@ return function() expect(promise._values[1]).to.equal(5) end) + it("should run andThens on a new thread", function() + local bindable = Instance.new("BindableEvent") + + local resolve + local parentPromise = Promise.new(function(_resolve) + resolve = _resolve + end) + + local deadlockedPromise = parentPromise:andThen(function() + bindable.Event:Wait() + return 5 + end) + + local successfulPromise = parentPromise:andThen(function() + return "foo" + end) + + expect(parentPromise:getStatus()).to.equal(Promise.Status.Started) + resolve() + expect(successfulPromise:getStatus()).to.equal(Promise.Status.Resolved) + expect(successfulPromise._values[1]).to.equal("foo") + expect(deadlockedPromise:getStatus()).to.equal(Promise.Status.Started) + end) + it("should chain onto resolved promises", function() local args local argsLength