Reputation: 16695
After some experimentation, I've ended up with the following code, trying to replicate the C# await functionality:
var promise = new WinJS.Promise(MyFunc())
.then(function () {
// Second function which uses data set-up in the first
MyFunc2();
});
'MyFunc()' executes correctly, but 'MyFunc2()' does not, and the program crashes. What am I misunderstanding about the Promise object?
(This is using Windows 8)
EDIT:
The full code for MyFunc() is now as follows:
function MyFunc() {
var foldername = "Folder";
var filename = "readme.xml";
var promise = Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync(foldername).then(function (folder) {
folder.getFileAsync(filename).then(function (file) {
var loadSettings = new Windows.Data.Xml.Dom.XmlLoadSettings;
loadSettings.prohibitDtd = false;
loadSettings.resolveExternals = false;
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file, loadSettings).then(function (doc) {
dataText = doc.getXml();
xmlDoc = doc;
}, function (error) {
output.value = "Error: Unable to load XML file";
output.style.color = "red";
}, function (error) {
output.value = "Error: Unable to load XML file";
output.style.color = "red";
})
})
});
return promise;
};
The result now is that 'MyFunc2()' executes before 'MyFunc()' completes. `MyFunc2() uses the global variable xmlDoc, which is therefore undefined at that time.
Upvotes: 3
Views: 1420
Reputation: 45173
You should chain all the promises together and then wait on the final promise.
function MyFunc() {
var promise = Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync(foldername).then(function (folder) {
return folder.getFileAsync(filename);
}).done(function (file) {
var loadSettings = new Windows.Data.Xml.Dom.XmlLoadSettings;
loadSettings.prohibitDtd = false;
loadSettings.resolveExternals = false;
return Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file, loadSettings);
}).then(function (doc) {
dataText = doc.getXml();
xmlDoc = doc;
return doc; // whatever the result is
}, function (error) {
output.value = "Error: Unable to load XML file";
output.style.color = "red";
});
return promise;
}
Then you can chain on the promise returned by MyFunc
:
var promise = MyFunc().then(function(doc) { MyFunc2(...); });
Upvotes: 3
Reputation: 1176
All right, given the edit, you will have to use a slightly different approach. You will need to make MyFunc() actually return the promise variable you are creating. This will allow you to chain MyFunc
to MyFunc2
. So you would do something like this:
var promise = Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync(foldername).then(function (folder) {
folder.getFileAsync(filename).done(function (file) {
var loadSettings = new Windows.Data.Xml.Dom.XmlLoadSettings;
loadSettings.prohibitDtd = false;
loadSettings.resolveExternals = false;
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file, loadSettings).then(function (doc) {
dataText = doc.getXml();
xmlDoc = doc;
}, function (error) {
output.value = "Error: Unable to load XML file";
output.style.color = "red";
});
...
return promise;
Assuming that's the only promise in MyFunc()
. If not, you can either chain all the promises together, or put them all in an array and return, for example, WinJS.Promise.join(promiseArray)
.
Now that you are returning a promise from MyFunc(), you can use then
to chain it.
var promise = MyFunc().then(function () {
// Second function which uses data set-up in the first
MyFunc2();
});
If MyFunc2
also contains async code, you could return those promises as well, and keep chaining as long as you needed to.
var promise = MyFunc().then(function () {
// Second function which uses data set-up in the first
return MyFunc2();
}).then(function () {
//And on and on...
});
Upvotes: 1