0

非ブロッキングコールバック関数で親関数を再帰的に呼び出すことは可能ですか?

例えば:

function checkValidZip(zipInput) {
    if (!zipInput.trim().match(/^(\d{5})$/g)) {

      userInput("Please enter a valid 5 digit shipping zip code", function(zip){
        //recursively call the parent function to check for valid zip 
        //(and continue to prompt the user until they enter proper zip)
        return checkValidZip(zip);
      });

    }
    //and return (only) the valid zip
    return output(zipInput);

 }

function userInput(param1, callback){

    input = prompt(param1);
    callback(input);
}

function output(param){

   alert(param);

}
checkValidZip(prompt("hello"));

http://jsbin.com/omubab/1/edit

明らかに問題は、コードがコールバック関数の呼び出しを待たずに実行を継続し (したがって、この例では zip をチェックしない)、再帰関数の追加の反復が親が戻るまで呼び出されないことです (この例では例return output(zipInput);)。

繰り返しますが、コールバックとして「自己呼び出し」再帰関数を持つことは可能ですか?

4

2 に答える 2

2

else output(zipInput)この特定の例では、 の最後にを使用するだけで、妥当と思われる動作を得ることができますcheckValidZip

checkValidZipより一般的には、コールバックを取得したい場合があります。

function checkValidZip(zipInput, callback) {
    if (!zipInput.trim().match(/^(\d{5})$/g)) {

    userInput("Please enter a valid 5 digit shipping zip code", function(zip){
        //recursively call the parent function to check for valid zip 
        //(and continue to prompt the user until they enter proper zip)
        checkValidZip(zip,callback);
    });

    }
    //and return (only) the valid zip
    else callback(zipInput);
}

checkValidZip(prompt("hello"),output);
于 2013-05-22T18:29:39.077 に答える
1

はい、しかし、これは好きではありません。Promise を使用できます。

function checkValidZip(zipInput) {
    var promise = new Promise();
    if (!zipInput.trim().match(/^(\d{5})$/g)) {
        userInput("Please enter a valid 5 digit shipping zip code", function(zip){
            checkValidZip(zip).done(function () {
                promise.resolve(zip);
            });
        });
    }
    return promise;
}

checkValidZip(prompt("hello")).done(function (zip) {
    console.log("valid zip:", zip);
}

Promise はネイティブでは利用できません。Google で好きなライブラリを探してください。jQueryにも1つあります。

于 2013-05-22T18:25:14.600 に答える