为什么我无法访问一个“then”块中的父范围变量,但我确实可以在后续块中访问?

时间:2017-07-19 13:35:26

标签: javascript ember.js ecmascript-6 es6-promise

我正在为一个开源的Ember应用做贡献,我正在尝试将多个承诺链接在一起。下面代码的目的是将用户设置为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中无法访问它。上面的代码,特别是使用首选项doc和用户对象传递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这样做?

1 个答案:

答案 0 :(得分:0)

从我所看到的,userName在你的代码中没有大写字母N(所以它是一个不同的变量):

}).then((user) => {
   let configDB = this.get('configDB');
   let preferences = configDB.get('preferences');
   return preferences[username] || preferences['default'];

您说此代码仅用于说明目的。最好知道返回错误消息的实际代码是什么以获得更好的想法。