2016-04-18 3 views
0

Ich erhalte ein Formular (über XMPP, XEP-0004), erstelle einen interaktiven Formulardialog dafür und sende dann das Formular, wenn der Dialog geschlossen wird.Wie man Versprechungen in einem interaktiven Anruf verwendet?

Der Code (etwa der Einfachheit halber angenähert):

function form(name, callback) { 
    server.getForm(name, function(response) { 
    callback(response.formFields, function (data) { 
     server.submitForm(name, data); 
    }); 
    }); 
} 

function main() { 
    form('example', function(fields, callback) { 
    var dialog = ui.formDialog(fields); 
    dialog.addButton('submit', function(data) { 
     callback(data); 
    }); 
    dialog.show(); 
    }); 
} 

Beachten Sie, wie der Anrufer und Angerufenen Austausch Rückrufe - in eine Richtung, für die Felder vom Server abgerufen; in der anderen für die vom Benutzer eingereichten Daten.

Ich habe kürzlich JS Promises entdeckt und ich würde gerne wissen, ob sie die Callbacks eleganter ersetzen könnten.

Ich habe so weit wie:

function form(name) { 
    return new Promise((resolve, reject) => { 
    server.getForm(
     name, 
     (response) => { resolve(response.formFields) }, 
     reject 
    ); 
    }); 
} 

function main() { 
    form('example').then((fields) => { 
    var dialog = ui.formDialog(fields); 
    dialog.addButton('submit', /* ... */); 
    }); 
} 

Aber jetzt stecken Ich bin, weil ich keine Möglichkeit haben, die Veranstaltungs-Taste, um den Anruf form() einreichen zurücklaufen.

Ich kann nicht einfach ein Versprechen für den Dialog entweder erstellen, weil ich zuerst dieses Versprechen erstellen musste, um es an form() zu übergeben, aber ich muss das Versprechen von form() aufgelöst werden, bevor ich erstellen kann der Dialog. Es gibt eine Art Bootstrap-Problem.

Gibt es eine Möglichkeit, Versprechungen hier zu verwenden, oder sollte ich mit der Weitergabe von Callbacks fortfahren?

Antwort

2

Sie könnten das Problem in drei Teile brechen:

  1. form - Rufen Sie die Form - Funktion, die den Namen übernimmt und die mit den Feldern aufgelöste Promise zurückgibt.
  2. askUser - Sammeln Eingabe - Funktion, die Felder annimmt, Formular anzeigt und ein Versprechen mit den gesendeten Daten zurückgibt.
  3. submit - Formular senden - Funktion, die Daten übernimmt und ein Versprechen des Netzwerkergebnisses zurückgibt.

Sie können als die drei zusammen komponieren:

form('example') 
    .then(askUser) 
    .then(submit) 
    .catch(errorHandler) 

der ein Versprechen schließlich gelöst mit dem Sendevorgang zurückkehren würde.

1

Sie können Callback trotzdem an die Antwort übergeben. Übergeben Sie einfach das Array der Antwort und des Rückrufs an die resolve. Und innerhalb .then Rückruf können Sie das Array zerstören. Kurz gesagt können Sie etwas wie schreiben: response => resolve([response.formFields, **your_callback**]) und .then(([fields, callback]) .... Aber meiner Meinung nach ist der Code, stinkende und Sie sollten from Funktion in zwei unabhängige Funktionen zerlegen Rückruf zu vermeiden vorbei hin und her

1

form Wraps sein Verhalten um einen Rückruf, Sie können diesen Rückruf nicht wirklich vermeiden, ohne form in zwei Funktionen zu teilen. Es ist jedoch völlig in Ordnung - es ist bekannt als disposer pattern.

Sie würden es wie folgt verwenden:

function form(name, callback) { 
    return server.getForm(name).then(function(response) { 
    return callback(response.formFields); 
    }).then(function (data) { 
    return server.submitForm(name, data); 
    }).catch(function(e) { 
    console.error(e); // or display it in the form, or whatever 
    }); 
} 

function main() { 
    return form('example', function(fields) { 
    return new Promise(function(resolve, reject) { 
     var dialog = ui.formDialog(fields); 
     dialog.addButton('submit', resolve); 
     dialog.show(); 
    }); 
    }); 
}