2017-07-26 1 views
0

Ich möchte eine Funktion verwenden, um ein Bereichsobjekt zurückzugeben, aber da die Funktion asynchron ist, ist mein Code immer noch null. Wie erzwinge ich den Code auf die Funktion getCurrentRangeSelection warten, damit ich das Objekt stattdessen undefined bekommen kann?Warte auf eine asynchrone Funktion Rückgabe eines Bereichsobjekts


EDIT 1 - Rick Kirkham: Ich habe den Code so jetzt vereinfacht es möglich ist, nur um es im Call Standard Basic API einzufügen (JavaScript) Vorlage in ScriptLab es zu testen.

Nach Promises stundenlang studieren, ich glaube, ich bin in der Nähe zu dem, was ich will, aber es immer noch nicht funktioniert:

$("#run").click(run); 

function run() { 
    var currentRangeSelection; 

    return Excel.run(function (context) { 
     return context.sync() 
      .then(function() { 
       return getCurrentRangeSelection(currentRangeSelection) 
      }) 
      .then(function() { 
       // this returns an error because currentRangeSelection is undefined: 
       console.log("Outside the function: " + currentRangeSelection.address); 
       currentRangeSelection.select(); 
       return context.sync(); 
      }) 
    }) 
     .catch(function (error) { 
      console.log(error); 
     }); 
} 

function getCurrentRangeSelection(rangeSelection) { 
    return Excel.run(function (context) { 
     return context.sync() 
      .then(function() { 
       rangeSelection = context.workbook.getSelectedRange(); 
       rangeSelection.load(); 
       return context.sync(); 
      }) 
      .then(function() { 
       // this works: 
       console.log("Inside the function: " + rangeSelection.address); 
       return context.sync(); 
      }); 
    }); 
} 

Wie Sie nun die Funktion ein Promise sehen gibt, weil es (Ich denke) der Rückgabewert von Excel.run Funktion, und jetzt gebe ich den gewünschten Rückgabebereich als Parameter, aber immer noch nicht funktioniert. Weitere Tipps?


EDIT 2 - Rick Kirkham

(1) Ich habe versucht, eine Funktion zu erstellen, die ein Versprechen zurück, so konnte ich es in der Anrufer then Kette einfügen. Aus diesem Grund bestand meine einzige Entscheidung darin, als Parameter den Parameter zu übergeben, der den Bereich zurückgibt.

(2) Ja, ich stimme Ihnen zu. Ich denke (1), warum ich überhaupt kein Entfernungsobjekt zurückgeschickt habe.

(3) Ja, das habe ich behoben.

(4) Die ursprüngliche Funktion war komplexer und eine einzige Methode von Office-JS API würde nicht zurückgeben, was ich wirklich wollte. Ich mein Problem gelöst, indem Sie diese:

$("#run").click(run); 

function run() { 
    var testRange; 

    return Excel.run(function (context) { 
     return context.sync() 
      .then(function() { 
       testRange = getCurrentRangeSelection(context); 
       testRange.load(); 
       return context.sync(); 
      }) 
      .then(function() { 
       console.log(testRange.address); // this works 
       return context.sync(); 
      }); 
    }).catch(function (error) { 
     console.log(error); 
    }); 
} 


function getCurrentRangeSelection(context) { 
    var rangeSelection = context.workbook.getSelectedRange(); 
    var activeWorksheet = context.workbook.worksheets.getActiveWorksheet(); 
    var usedRange = activeWorksheet.getUsedRange(); 
    return usedRange.getIntersection(rangeSelection); 
} 

Meine nächste Frage, die Sie mit Ihrem bearbeiten beantwortet: „Was passiert, wenn ich die Funktion getCurrentRangeSelection zurückzukehren ein bereits loaded Objekt gesucht“

Danke für das Beispiel und die Antworten!

+0

FYI dieser Teil des Problems mit dem ersten Code war, dass Sie effektiv zwei verschiedene 'Excel.run'-s. Dinge können wirklich verwirrend werden, wenn du es tust. Ich habe kürzlich einen langen Abschnitt dazu in [mein Buch] hinzugefügt (https: // leanpub.com/buildingofficeaddins), "Verwenden von Objekten außerhalb des" linearen "Excel.run- oder Word.run-Flusses (z. B. bei einem Klick-Klick-Callback, in einem setInterval usw.)". Allerdings trifft dieser Fall nicht wirklich auf Sie zu, da Sie * einen linearen Fluss haben wollen - und wenn es sich um einen linearen Fluss handelt, dann sollte ein einzelner "Excel.run" ausreichen. Hoffe, das macht Sinn. –

+0

Ich bin mir nicht sicher, ob du noch eine Frage hast oder ob alles schon von Ricky beantwortet wurde - aber wenn du es trotzdem tust, frag es einfach in einem separaten StackOverflow-Thread. –

+0

Alles ist beantwortet, danke für den Kommentar und ja, ich habe dein Buch über diesen Teil gelesen und endlich das Konzept verstanden! –

Antwort

2

Versuchen Sie Folgendes: Redesign der getCurrentRangeSelection Funktion, um ein Promise-Objekt zurückzugeben. Dann rufen Sie die then Methode des Versprechens Objekt currentRangeSelection.select()

bearbeiten im Lichte der Bemerkungen des OP zu nennen unten und umgeschrieben Frage:

Bitte gehen Sie auf this sample und sehen Sie die getDocumentFilePath Funktion in der home.js Datei. Strukturieren Sie Ihre getCurrentRangeSelection Methode wie es und übergeben Sie das Kontextobjekt als Parameter. Verwenden Sie dann das Kontextobjekt, um den aktuell ausgewählten Bereich mit der Methode context.workbook.getSelectedRange() abzurufen. Dann übergeben Sie die Sache, die Sie zurückgeben wollen (der aktuell gewählte Bereich, nehme ich an) als Parameter an die Methode resolve.

+0

Danke, aber ich weiß nicht, wie ich das machen soll. Irgendwelche Referenzen? –

+0

Nur Bing "JavaScript Promises" und Sie werden viele Hits einschließlich Anfängerhandbücher und Tutorials bekommen. –

+0

Danke für den Tipp, aber es funktioniert immer noch nicht. Können Sie die bearbeiteten Überlegungen sehen? –

Verwandte Themen