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

その結果、「MyFunc()」が完了する前に「MyFunc2()」が実行されます。`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;
}

次に、によって返された promise をチェーンできますMyFunc

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

さて、編集を考えると、少し異なるアプローチを使用する必要があります。MyFunc()が実際に作成しているpromise変数を返すようにする必要があります。これにより、にチェーンすることができMyFuncますMyFunc2。したがって、次のようなことを行います。

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は、それらのpromiseも返し、必要な限りチェーンを続けることができます。

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 に答える