3

经过一些实验,我最终得到了以下代码,尝试复制 C# await 功能:

var promise = new WinJS.Promise(MyFunc())
    .then(function () {
        // Second function which uses data set-up in the first
        MyFunc2();
    });

'MyFunc()' 正确执行,但 'MyFunc2()' 没有,程序崩溃。我对 Promise 对象有什么误解?

(这是使用 Windows 8)

编辑:

MyFunc() 的完整代码现在如下:

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;
};

现在的结果是 'MyFunc2()' 在 'MyFunc()' 完成之前执行。`MyFunc2() 使用全局变量 xmlDoc,因此当时未定义。

4

2 回答 2

3

您应该将所有承诺链接在一起,然后等待最终的承诺。

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;
}

然后你可以链接返回的承诺MyFunc

var promise = MyFunc().then(function(doc) { MyFunc2(...); });
于 2013-01-09T20:14:32.550 回答
1

好吧,鉴于编辑,您将不得不使用稍微不同的方法。您需要让 MyFunc() 实际上返回您正在创建的承诺变量。这将允许您链接MyFuncMyFunc2. 所以你会做这样的事情:

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;

假设这是MyFunc(). 如果没有,您可以将所有 Promise 链接在一起,或者将它们全部放在一个数组中并返回,例如WinJS.Promise.join(promiseArray).

现在您从 MyFunc() 返回了一个 Promise,您可以使用then它来链接它。

var promise = MyFunc().then(function () {
    // Second function which uses data set-up in the first
    MyFunc2();
});

如果MyFunc2还包含异步代码,您也可以返回这些承诺,并根据需要保持链接。

var promise = MyFunc().then(function () {
    // Second function which uses data set-up in the first
    return MyFunc2();
}).then(function () {
    //And on and on...
});
于 2013-01-09T16:54:49.047 回答