--[=[
	Like then, but the value passed down the chain is the resolved value of the promise, not
	the value returned from onFulfilled or onRejected

	Will still yield for the result if a promise is returned, but will discard the result.

	@param onFulfilled function
	@param onRejected function
	@return Promise<T> -- Returns self
]=]

function Promise:Tap(onFulfilled, onRejected)
	-- Run immediately like then, but we return something safer!
	local result = self:Then(onFulfilled, onRejected)
	if result == self then
		return result
	end

	-- Most of the time we can just return the same
	-- promise. But sometimes we need to yield
	-- for the result to finish, and then resolve that result to a new result
	if result._fulfilled then
		return self
	elseif result._rejected then
		return self
	elseif result._pendingExecuteList then
		-- Definitely the most expensive case, might be able to make this better over time
		local function returnSelf()
			return self
		end

		return result:Then(returnSelf, returnSelf)
	else
		error("Bad result state")
	end
end
