Need help improving this code

Currently, I am creating a data saving system with ProfileService. Right now, I have mostly finished the load function, but it seems really messy and i’m not sure how to clean it.

function DataStoreObject:LoadDataAsync(player: Player, reconcileData: boolean?)
	reconcileData = ArchUtil.optionalParam(reconcileData, true)

	local PlayerDataObject = setmetatable({ }, {__index = PlayerDataObject})
	local PlayerData = self.DataStore:LoadProfileAsync(string.format(Settings.KeyStringPattern, player.UserId))
	
	local Created = os.time()

	self.SessionLockClaimed:Fire(player)
	
	PlayerDataObject.LoadedAt = Created

	PlayerDataObject.Name = self.Name :: string
	PlayerDataObject.Player = player :: Player
	PlayerDataObject.Loaded = false :: boolean

	PlayerDataObject.KeyChanged = Signal.new() :: ScriptSignal
	PlayerDataObject.KeyAdded = Signal.new() :: ScriptSignal
	PlayerDataObject.KeyRemoved = Signal.new() :: ScriptSignal
	PlayerDataObject.GlobalKeyRecieved = Signal.new() :: ScriptSignal

	task.spawn(function()
		if PlayerData then
			PlayerData:AddUserId(player.UserId)

			if reconcileData then
				PlayerData:Reconcile()
			end

			PlayerData:ListenToRelease(function()
				LoadedPlayers[self.Name][player] = nil
				
				setmetatable(PlayerDataObject, nil)
				table.clear(PlayerDataObject)

				player:Kick(string.format(PlayerDataSessionLockError, player.UserId))
			end)

			if player:IsDescendantOf(Players) then
				LoadedPlayers[self.Name][player] = PlayerData
				
				for _, globalKey in ipairs(PlayerData.GlobalUpdates:GetActiveUpdates()) do
					PlayerData.GlobalUpdates:LockActiveUpdate(globalKey[1])
				end
				
				PlayerData.GlobalUpdates:ListenToNewActiveUpdate(function(id, data)
					PlayerData.GlobalUpdates:LockActiveUpdate(id)
				end)
				
				PlayerData.GlobalUpdates:ListenToNewLockedUpdate(function(id, data)
					PlayerDataObject.GlobalKeyRecieved:Fire(data.key_type, data.sent_data)
					PlayerData.GlobalUpdates:ClearLockedUpdate(id)
				end)
				
				PlayerDataObject.Loaded = true
			else
				PlayerData:Release()
			end
		else
			player:Kick(string.format(PlayerDataLoadError, player.UserId))
			console.warn(string.format(PlayerDataLoadError, player.UserId))
		end
	end)
	
	repeat task.wait() until PlayerDataObject.Loaded

	return PlayerDataObject
end

I would be very grateful if you could help! Thanks