Skip to main content
Register now for TDX! Join the must-attend event to experience what’s next and learn how to build it.

Verwenden von Future-Methoden

Lernziele

Nachdem Sie diese Lektion abgeschlossen haben, haben Sie Folgendes gelernt:

  • Zeitpunkt für die Verwendung von Future-Methoden
  • Einschränkungen bei der Verwendung von Future-Methoden
  • Verwenden von Future-Methoden für Callouts
  • Future-Methoden – bewährte Vorgehensweisen
Hinweis

Hinweis

Lernen Sie auf Deutsch? Beginnen Sie die Aufgabe in einem Trailhead Playground in der Sprache Deutsch und verwenden Sie für die Navigation die in Klammern angegebenen Übersetzungen. Kopieren und fügen Sie nur die Angaben in Englisch ein, da zur Überprüfung der Aufgabe Daten in Englisch benötigt werden. Wenn Sie die Aufgabe in Ihrer deutschen Organisation nicht bestehen, empfehlen wir Ihnen folgende Vorgehensweise: (1) Stellen Sie das Gebietsschema auf USA um, (2) legen Sie Englisch als Sprache fest (Anweisungen dazu finden Sie hier) und (3) klicken Sie erneut auf die Schaltfläche "Check Challenge" (Aufgabe überprüfen).

Weitere Details dazu, wie Sie die übersetzte Trailhead-Umgebung optimal nutzen können, finden Sie unter dem Badge "Trailhead in Ihrer Sprache".

Mit Trail Together einem Dozenten folgen

Möchten Sie bei diesem Schritt einem Dozenten folgen?

(Dieser Clip beginnt bei Minute 09:39, für den Fall, dass Sie zurückspringen und den Anfang des Schritts noch einmal sehen möchten.) 

Future-Apex

(Dieser Clip beginnt bei Minute 09:39, für den Fall, dass Sie zurückspringen und den Anfang des Schritts noch einmal sehen möchten.)

Note

Bei Verwendung der synchronen Verarbeitung erfolgen alle Methodenaufrufe aus dem gleichen Thread, der auch den Apex-Code ausführt, und es ist keine weitere Verarbeitung möglich, bis der Prozess abgeschlossen ist. Sie können Future-Methoden für jeden Vorgang verwenden, den Sie asynchron in seinem eigenen Thread ausführen möchten. Es profitieren also alle Seiten von der asynchronen Verarbeitung.

Future-Methoden werden meist für folgende Zwecke verwendet:

Syntax von Future-Methoden

Die angegebenen Parameter müssen primitive Datentypen oder Sammlungen primitiver Datentypen sein. Vor allem dürfen bei Future-Methoden keine standardmäßigen oder benutzerdefinierten Objekte als Argumente angegeben werden. Im allgemeinen wird der Methode eine List (Liste) mit Datensatz-IDs übergeben, die asynchron verarbeitet werden sollen.

public class SomeClass {
  @Future
  public static void someFutureMethod(List<Id> recordIds) {
    List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
    // process account records to do awesome stuff
  }
}
Note

Der Grund, aus dem Objekte nicht als Argumente an Future-Methoden übergeben werden dürfen, besteht darin, dass sich das Objekt zwischen dem Zeitpunkt des Methodenaufrufs und dem Zeitpunkt der eigentlichen Ausführung ändern kann. Sie erinnern sich? Future-Methoden werden ausgeführt, wenn Systemressourcen verfügbar werden. Die Future-Methode könnte sonst bei ihrer tatsächlichen Ausführung einen alten Objektwert enthalten, was alle möglichen negativen Auswirkungen haben könnte.

Callout-Beispielcode

Hier muss unbedingt darauf hingewiesen werden, dass es nicht garantiert ist, dass Future-Methoden in derselben Reihenfolge ausgeführt werden, in der sie aufgerufen wurden. Wir sagen es noch einmal, denn es ist wichtig, dass Sie sich daran erinnern: Future- Methoden werden nicht garantiert in der gleichen Reihenfolge ausgeführt, in der sie aufgerufen werden. Bei der Verwendung von Future-Methoden besteht zudem die Möglichkeit, dass zwei Future-Methoden gleichzeitig ausgeführt werden. Dies kann zu einer Datensatzsperre und einem unschönen Laufzeitfehler führen, wenn die beiden Methoden denselben Datensatz aktualisieren.

Note

public class SMSUtils {
    // Call async from triggers, etc, where callouts are not permitted.
    @Future(callout=true)
    public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
        String results = sendSMS(fromNbr, toNbr, m);
        System.debug(results);
    }
    // Call from controllers, etc, for immediate processing
    public static String sendSMS(String fromNbr, String toNbr, String m) {
        // Calling 'send' will result in a callout
        String results = SmsMessage.send(fromNbr, toNbr, m);
        insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
        return results;
    }
}

Testklassen

Das Testen von Future-Methoden unterscheidet sich etwas vom normalen Apex-Testen. Zum Testen von Future-Methoden fügen Sie Ihren Testcode zwischen die Testmethoden startTest() und stopTest() ein. Wenn stopTest() ausgeführt wird, werden alle diese gesammelten, asynchronen Prozesse synchron ausgeführt. Sie können dann sicherstellen, dass der asynchrone Aufruf richtig funktioniert hat.

Note

Da der Testcode keine echten Callouts an externe Systeme senden kann, müssen Sie den Callout für die Testabdeckung simulieren. Ausführliche Details zum Simulieren von Callouts beim Testen finden Sie im Modul Apex-Integrationsservices.

Hier sehen Sie unsere simulierte Callout-Klasse, die beim Testen verwendet wird. Das Apex-Test-Framework nutzt diese "simulierte" Antwort, anstelle den tatsächlichen Callout an den REST API-Endpunkt durchzuführen.

@IsTest
public class SMSCalloutMock implements HttpCalloutMock {
    public HttpResponse respond(HttpRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"status":"success"}');
        res.setStatusCode(200);
        return res;
    }
}

Die Testklasse enthält eine einzige Testmethode (testSendSms() in diesem Beispiel), die sowohl die asynchrone als auch die synchrone Methode testet, da die asynchrone die synchrone Methode aufruft.

@IsTest
private class Test_SMSUtils {
  @IsTest
  private static void testSendSms() {
    Test.setMock(HttpCalloutMock.class, new SMSCalloutMock());
    Test.startTest();
      SMSUtils.sendSMSAsync('111', '222', 'Greetings!');
    Test.stopTest();
    // runs callout and check results
    List<SMS_Log__c> logs = [select msg__c from SMS_Log__c];
    Assert.areEqual(1, logs.size());
    Assert.areEqual('success', logs[0].msg__c);
  }
}

Bewährte Vorgehensweisen

Da bei jedem Aufruf einer Future-Methode eine Anforderung zur asynchronen Warteschlange hinzugefügt wird, sollten Sie Designmuster vermeiden, bei denen in einem kurzen Zeitraum viele Future-Anforderungen hinzugefügt werden. Wenn Ihr Design das Potenzial hat, 2000 oder mehr Anforderungen gleichzeitig hinzuzufügen, könnten Anforderungen aufgrund der Datenflusssteuerung verzögert werden.

Hier sind einige bewährte Vorgehensweisen, die Sie im Hinterkopf behalten sollten:

  • Stellen Sie sicher, dass Future-Methoden so schnell wie möglich ausgeführt werden.
  • Versuchen Sie bei der Verwendung von Webservice-Callouts, alle Callouts innerhalb derselben Future-Methode zu bündeln, anstatt für jeden Callout eine separate Future-Methode zu verwenden.
  • Führen Sie gründliche Tests in der gewünschten Skalierung durch. Testen Sie, ob ein Auslöser, der die @future-Aufrufe in die Warteschlange einreiht, eine Auslösersammlung von 200 Datensätzen verarbeiten kann. Damit können Sie die Wahrscheinlichkeit von Verzögerungen für das Design mit dem aktuellen und künftigen Volumen feststellen.
  • Dies ist effizienter als die Erstellung einer Future-Anforderung für jeden Datensatz.

Wichtige Punkte

Future-Methoden sind ein mächtiges Tool, doch große "Macht" bedeutet auch große Verantwortung. Hier sind einige Punkte, die Sie bei der Arbeit mit Future-Methoden beachten sollten:

  • Methoden mit der Anmerkung @future müssen statische Methoden sein und dürfen nur einen void-Typ zurückgeben.
  • Die angegebenen Parameter müssen primitive Datentypen oder Sammlungen primitiver Datentypen sein. Bei Future-Methoden dürfen keine Objekte als Argumente angegeben werden.
  • Future-Methoden werden nicht zwingend in der Reihenfolge ausgeführt, in der sie aufgerufen werden. Es besteht zudem die Möglichkeit, dass zwei Future-Methoden gleichzeitig ausgeführt werden. Dies kann zu einer Datensatzsperre führen, wenn die beiden Methoden denselben Datensatz aktualisieren.
  • Future-Methoden können weder in Visualforce-Steuerfeldern in getMethodName() oder setMethodName() noch im Konstruktor verwendet werden.
  • Eine Future-Methode kann nicht innerhalb einer Future-Methode aufgerufen werden.
  • Die Methoden getContent() und getContentAsPDF() dürfen in Methoden mit der Anmerkung @future nicht verwendet werden.
  • Pro Apex-Aufruf dürfen maximal 50 Future-Methoden aufgerufen werden. Zusätzlich gibt es noch ein Limit für die Anzahl der Aufrufe innerhalb von 24 Stunden.

Ressourcen

Teilen Sie Ihr Trailhead-Feedback über die Salesforce-Hilfe.

Wir würden uns sehr freuen, von Ihren Erfahrungen mit Trailhead zu hören: Sie können jetzt jederzeit über die Salesforce-Hilfe auf das neue Feedback-Formular zugreifen.

Weitere Infos Weiter zu "Feedback teilen"