我遇到异步JavaScript问题,无法将回调方法中收到的值保存为对象文字。我正在制作Chrome扩展程序并使用chrome.cookies.getAll
方法,并且能够获取Cookie并在回调中读取它们,但我无法将值保存到对象中。我仍然掌握对象和异步JavaScript,并且可以真正使用一些帮助。
这是代码
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);
});
}
};
由于回调在
之后执行console.log('session in object : ');
console.log(this.activeCookie['sid']);
this.activeCookie['sid']
是null
。
我想知道如何将值保存到对象中,以便异步方法将其保存到对象中,然后在setupSession()
完成后执行后续代码行。
答案 0 :(得分: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);
});
});
}
用法变为:
app.init().then(function() {
/* code that should execute after init */
});