涉及循環調用的異步編程技巧

先看問題

login_label: login(user, pass, function(result) {
    doSomeThing_label: doSomeThing(result, function(err) {
        switch(err) {
        case 'disconnect':  // 第二次失敗,從新登陸
            goto login_label;  // 這隻表示算法,並不能執行
        case 'retry':  // 第一次執行失敗,重試
            goto doSomeThing_label;  // 這隻表示算法,並不能執行
        default:
            logout(function() {
                console.log('finish');
            }
        }
    }
}

使用Steps解決實例(能夠運行的。例子中有沒有異步過程都不是問題,不信的能夠本身改改驗證)

var Steps = require("promise-tiny/Steps");

new Steps({
    user: 'foo',
    pass: 'foolish',
    loginCount: 0,
    doSomeThingCount: 0
}) .on('Begin', function(next) {    // 從這裏開始
        next('login', [this.user, this.pass]);
    })
   .on('login', function(next, user, pass) {
        console.log('login("'+user+'", "'+pass+'")');

        this.loginCount++;

        var result = true;    // 假設login總能成功
        console.log('    第'+this.loginCount+'次login成功');
        console.log();
        next('doSomeThing', '一些要作的事情...');
    })
   .on('doSomeThing', function(next, ...args) {
        console.log('doSomeThing("'+args+'")');

        this.doSomeThingCount++;

        if(this.doSomeThingCount === 1) {    // 假設第一次作不成功,重試一次
            console.log('    第'+this.doSomeThingCount+'次doSomeThing失敗,再試一次');
            next('doSomeThing', args);
        }
        else if(this.loginCount === 1) {    // 假設第二次作不成功,從新login
            console.log('    第'+this.doSomeThingCount+'次doSomeThing失敗,從新login');
            next('login', [this.user, this.pass]);
        }
        else {
            console.log('    第'+this.doSomeThingCount+'次doSomeThing完成了,要退出了');
            next('logout');
        }
        console.log();
    })
   .on('logout', function(next) {
        console.log('logout()');
    })

運行結果算法

login("foo", "foolish")
    第1次login成功

doSomeThing("一些要作的事情...")
    第1次doSomeThing失敗,再試一次

doSomeThing("一些要作的事情...")
    第2次doSomeThing失敗,從新login

login("foo", "foolish")
    第2次login成功

doSomeThing("一些要作的事情...")
    第3次doSomeThing完成了,要退出了

logout()
相關文章
相關標籤/搜索