【发布时间】:2017-07-19 13:35:25
【问题描述】:
我正在为一个开源 Ember 应用程序做出贡献,并且我正在尝试将多个 Promise 链接在一起。下面代码的目的是将用户设置到 PouchDB 存储的 current_user 文档中,然后将他们的 i18n 首选项设置到 preferences 存储中。代码如下:
setCurrentUser(userName) { // block 0
let config = this.get('configDB');
let sessionData = this.get('sessionData');
if (!userName && sessionData.authenticated) {
userName = sessionData.authenticated.name;
}
config.get('current_user').then((doc) => { // block 1
doc.value = userName;
config.put(doc);
return userName;
}).then((user) => { // block 2
let configDB = this.get('configDB');
let preferences = configDB.get('preferences');
let promises = { user, preferences };
return RSVP.hash(promises);
}).then((promises) => { // block 3
let { preferences } = promises;
let userName = promises.user.name || 'default';
this.set('i18n.locale', preferences[userName].i18n);
}).catch((err) => { // block 4
console.log(err);
config.put({_id: 'current_user', value: userName});
});
}
如您所见,userName 变量作为参数传入setCurrentUser 方法。因此,我希望能够在每个 then 块内的每个代码块内访问此参数。
但事实并非如此。我确实可以在块 0、1、3 中访问它,甚至在块 4 中的 catch 范围内都可以访问它。但由于某种原因,我无法在块 2 中访问它。上面的代码,特别是传递带有首选项文档和用户对象的 RSVP 对象,代表了一种使我的代码工作的 hacky 解决方法。但是,我更喜欢这样做:
setCurrentUser(userName) { // block 0
let config = this.get('configDB');
let sessionData = this.get('sessionData');
if (!userName && sessionData.authenticated) {
userName = sessionData.authenticated.name;
}
config.get('current_user').then((doc) => { // block 1
doc.value = userName;
config.put(doc);
return userName;
}).then((user) => { // block 2
let configDB = this.get('configDB');
let preferences = configDB.get('preferences');
return preferences[userName].i18n || preferences['default'].i18n;
}).then((i18nPreference) => { // block 3
this.set('i18n.locale', i18nPreference);
}).catch((err) => { // block 4
console.log(err);
config.put({_id: 'current_user', value: userName});
});
}
事实上,我已经尝试了上述方法,但我在块 2 内得到了 Uncaught ReferenceError: userName is not defined,因此被路由到 catch 块。
我的问题是,块 0/1/3/4 和块 2 之间有什么区别,这将允许第一个块访问 userName 但会阻止块 2 这样做?
【问题讨论】:
-
我有疑问,您要返回
userName,我们可以从那里输入}).then((user) => {吗?这行得通吗? -
@kumkanillam 我不明白你的意思。您的意思是删除
return userName;行并将}).then((user) => {向上移动1 行吗?那么我们会将什么传递给下一个then块? -
忽略我的cmets,这是我对promise的误解。对我来说,你的代码看起来不错。可以尝试评论此行
doc.value = userName; config.put(doc); -
您需要将代码缩减为可重现的示例。实际上,您绝对可以在所有块中访问该变量:jsfiddle.net/Laayk2g1
-
是否有可能在没有
userName的情况下调用setCurrentUser并且该块只是您出错的第一个地方?
标签: javascript ember.js ecmascript-6 es6-promise