2016-07-21 24 views
1

私は非同期JavaScriptの問題に遭遇しています。コールバックメソッドで受け取った値をオブジェクトリテラルとして保存できません。 Chrome拡張機能を作成してchrome.cookies.getAllメソッドを使用しており、クッキーを取得してコールバックで読み取ることができますが、その値をオブジェクトに保存できません。私はまだオブジェクトと非同期JavaScriptのハングを取得していると実際にいくつかの助けを使用することができます。非同期chrome.cookies.getAllの結果を使用

console.log('session in object : '); 
console.log(this.activeCookie['sid']); 

this.activeCookie['sid']null後にコールバックが実行されるため

は、ここでは、コード

var app = { 
    init: function() { 
     this.activeCookie = { 
      'sid': null 
     }; 
     this.setupSession(); 
     // shows null 
     console.log('session in object : '); 
     console.log(this.activeCookie['sid']); 
    }, 

    setupSession: function() { 
     var that = this; 

     function setCookiesAsync(that, cookie) { 
      console.log(cookie); 
      for(var i=0; i<cookie.length; ++i) { 
       if(cookie[i]['name'] === 'sid') { 
        that.activeCookie['sid'] = cookie[i]['value']; 
        // shows a token 
        console.log('session in callback : '); 
        console.log(that.activeCookie['sid']); 
       } 
      } 
     } 

     chrome.cookies.getAll({ 
      'url': ST.BaseUrl 
     }, function (cookie) { 
      setCookiesAsync(that, cookie); 

     }); 
    } 
}; 

です。

私は、非同期メソッドは、オブジェクトに保存しますので、私はオブジェクトに値を保存することができますし、setupSession()が完了した後、コードの次の行を実行する方法を疑問に思って。

+0

が、それは_really_共通の話題です。 – Xan

+0

うん、私はこれについて束を読んで、ここでいくつかの素晴らしい記事を見たが、オブジェクトに値を保存することはできません知っている。私はそれを開いたままにできますか?それを開いたままにすることはできますか? – user1807880

+0

あなたの 'init'関数は本質的に非同期でもあります。なぜなら、' init'が想定されているコードが本当に実行されるようにするためには、コールバックを取る必要があります後で実行します(つまり、 'setCookiesAsync'の終わりに) – Xan

答えて

2

この質問はvery canonical topicにありますが、特定の解決法を提供することも役立ちます。

init()の部分は、非同期に実行されます。これは、init()の実行が終了するまでに、そのコードのすべてがまだ実行されていないことを意味します。 その前に非同期部分が実行された直後のコードはありません。

initの後で具体的に実行したいコードがある場合(このコードをコールバックとして渡すなど)、これをコールバックとして渡して適切なコードに追加します場所:次のように続いて、コードを使用することができます

init: function(callback) { 
    this.activeCookie = { 
    'sid': null 
    }; 
    this.setupSession(callback); 
}, 

setupSession: function(callback) { 
    var that = this; 

    function setCookiesAsync(that, cookie) { 
    for(var i=0; i<cookie.length; ++i) { 
     if(cookie[i]['name'] === 'sid') { 
     that.activeCookie['sid'] = cookie[i]['value']; 
     } 
    } 
    // This is the point where all of init() has finished 
    if (typeof callback === "function") { callback(); } 
    } 

    chrome.cookies.getAll({ 
    'url': ST.BaseUrl 
    }, function(cookie) { 
    setCookiesAsync(that, cookie); 
    }); 
} 

app.init(function() { 
    /* code that should execute after init */ 
}); 

を別の方法として、あなたはPromisesを使用することができます。

init: function() { 
    this.activeCookie = { 
    'sid': null 
    }; 
    return this.setupSession(callback); // returns a Promise 
}, 

setupSession: function() { 
    return new Promise(function(resolve, reject) { 
    var that = this; 

    function setCookiesAsync(that, cookie) { 
     for(var i=0; i<cookie.length; ++i) { 
     if(cookie[i]['name'] === 'sid') { 
      that.activeCookie['sid'] = cookie[i]['value']; 
     } 
     } 
     // This is the point where all of init() has finished 
     resolve(); 
    } 

    chrome.cookies.getAll({ 
     'url': ST.BaseUrl 
    }, function (cookie) { 
     setCookiesAsync(that, cookie); 
    }); 
    }); 
} 

と使用方法は次のようになります(私もupvoted)

などよく練られた質問とだまされやすい人としてこれを閉じるため申し訳ありません
app.init().then(function() { 
    /* code that should execute after init */ 
}); 
+0

Chromeで非同期関数が使用されている理由については、最近の[loooooong answer](http://stackoverflow.com/a/38456419/934239)をご覧ください。 – Xan

+0

あなたはあなたが本当に役に立つXanよりも素晴らしいです。私はまだ約束の実装を理解して使用するよう努めていますが、コールバックの実装は完全に意味があります。ありがとうございました – user1807880

関連する問題