13

私は次のようなコードを持っています:

function test(obj) {

    if(//some conditon) {
        obj.onload();
    }else{
        obj.onerror();
    }
}


for(var i=0;i<4;i++){   

    test({
        onload:function(e){          
            //some code to run
        },
        onerror:function(e){
            break;
        }


    });
}

要点は、test()関数がXHRリクエストを作成する関数であり(実際にはAppcelerator TitaniumプラットフォームのAPIであるため、制御できません)、テスト関数を呼び出すために何かをループしています。onerror関数でループを中断する必要がありますが、中断がループまたはswitchステートメント内にないというエラーが表示されます。どうすればこれを書き直すことができますか?

4

6 に答える 6

14

コード サンプルが実際のコードを表している場合 (つまり、すべての処理が同じイベント ループ ティックで行われている場合)、次のようにすることができます。

function test(obj) {

    if (some_condition) {
        return obj.onload();
    } else {
        return obj.onerror();
    }
}

var result;
for(var i=0; i<4; i++){   

    result = test({
        onload:function(e){          
            //some code to run
            return true;
        },
        onerror:function(e){
            return false;
        }


    });

    if (!result) {
        break;
    }
}

それ以外の場合、非同期処理が行われている場合はtest、並列ではなく順次呼び出す必要があります。例えば、

function test(obj) {
    doSomeAjaxRequest(arguments, function (err, result) {
        if (some_condition) {
            obj.onload();
        } else {
            obj.onerror();
        }
    });
}

var f = function (i) {
    if (i >= 4) return;
    test({
        onload:function(e){          
            //some code to run
            f(i+1);
        },
        onerror:function(e){
            break;
        }
    });
}

f(0);
于 2012-08-07T09:19:38.420 に答える
3

ありえない。forループは同期プロシージャですが、Ajaxリクエストは同期プロシージャではありません。つまり、onerrorコールバックが発生すると、forループの実行はすでに完了しています。

別の方法として、エラーがまだ発生していないことを確認するチェックを成功ハンドラーに導入することもできます。

var errorOccured = false;
for(var i=0;i<4;i++){   

test({
    onload:function(e){   
        if(errorOccured) return;
        //some code to run
    },
    onerror:function(e){
        errorOccured = true;
    }


});
}
于 2012-08-07T09:16:17.830 に答える
3

少しハックかもしれませんが、ハンドラー関数を使用してこのようなことを行うことができます。

var handler = function(array, callback){
    for(var i=0, l=array.length, e=array[i]; i<l; ++i){
        if(true === handler.exit){
            handler.exit = false; //restore
            return;
        }
        callback.call(null, e);
    }
};
handler.exit = false; 

handler([1,2,3], function(e){
   console.log(e);
   if(2 === e){
       arguments.callee.caller.exit = true; // :-)
   }
});

これをテストしませんでしたが、呼び出しでも関数をスコープにバインドできますか?

var handler = function(a, f){
    this.exit = false;
    for(var i=0, l=a.length, e=a[i]; i<l; ++i){
        if(true === this.exit){
            this.exit = false; //restore
            return;
        }
        callback.call(this, e);
    }
};
handler([1,2,3], function(e){
   console.log(e);
   if(2 === e){
       this.exit = true;
   }
});
于 2012-10-23T12:11:21.737 に答える
0

test()関数内のループを壊すことはできません。この場合の最善の解決策は、test()関数内で例外をスローし、それをループでキャッチして中断することだと思います。

于 2012-08-07T09:16:17.440 に答える
0

「onload」コールバックを再帰的にすることはできますか?

つまり、「onload」ハンドラ内で「test」メソッドを呼び出すだけです。これは、すべてのリクエストを同時にではなく順番に起動することも意味します。

于 2012-08-07T09:24:26.807 に答える