如何确保正确的“this”;Promise.promisify
How to ensure correct "this" with Promise.promisify?
我正在尝试使用承诺与蓝鸟库重构我的nodejs服务器,但我被困在一个简单的问题。
从数据库中获取用户后,我想列出与该用户关联的所有通知类:
Bad Way (working…)
adapter.getUsers(function(users){
users.rows.forEach(function(item){
user = item.username;
adapter.getNotifications(user, function(notificationList){
console.log(notificationList);
})
});
});
优雅的暂定方式(不工作…)
var getNotifications = Promise.promisify(adapter.getNotifications);
adapter.getUsers().then(function(users) {
users.rows.forEach(function(item){
var dbUser = "sigalei/" + item.value.name;
console.log(dbUser);
return getNotifications(dbUser);
});
}).then(function(result){
console.log(result);
console.log("NOTIFICATIONLIST");
});
然而,当我执行这段代码时,我在getNotification方法中得到这个错误:
未处理的拒绝TypeError: Cannot read property 'nano' of undefined在适配器。getNotifications(/用户/DaniloOliveira/Workspace/sigalei-api/api/工具/couchdb-adapter.js: 387:30)/Users/DaniloOliveira/Workspace/sigalei-api/node_modules/bluebird/js/main/util.js:26:23)
编辑
在user2864740的宝贵评论之后,我注意到这个错误与一些范围问题有关。那么,为什么使用承诺方法后,方法不getNotifications识别"this"环境变量?
var Adapter = module.exports = function(config) {
this.nano = require('nano')({
url: url,
request_defaults: config.request_defaults
});
};
Adapter.prototype.getNotifications = function(userDb, done) {
var that = this;
console.log(that);
var userDbInstance = that.nano.use(userDb);
userDbInstance.view('_notificacao', 'lista',
{start_key: "[false]", end_key: "[false,{}]"},
function(err, body) {
if(err){ done(err); }
done(body);
});
};
这是调用"未绑定"方法时最常见的问题。
您可以将上下文作为选项传递给Promise.promisify
,使其绑定:
var getNotifications = Promise.promisify(adapter.getNotifications, {context: adapter});
或者,您需要.bind()
方法,或者在adapter
上调用新的getNotifications
函数(使用.call()
)。您也可以考虑使用Promise.promisifyAll(adapater)
,然后只调用adapter.getNotificationsAsync(…)
。
注意,这仍然不起作用。你不能简单地在循环中创建承诺——你需要显式地等待它们,并从then
回调中返回一个承诺,否则你返回的undefined
值将立即传递给下一个回调。
adapter.getUsers().then(function(users) {
return Promise.all(users.rows.map(function(item){
var dbUser = "sigalei/" + item.value.name;
console.log(dbUser);
return getNotifications(dbUser);
}));
}).then(function(results) {
for (var i=0; i<results.length; i++)
console.log("result:", results[i]);
});
在蓝鸟中,你也可以使用Promise.map(users.rows, …)
代替Promise.all(users.rows.map(…))
。
var getNotifications = Promise.promisify(adapter.getNotifications.bind(adapter));
或
var getNotifications = Promise.promisify(function () {
return adapter.getNotifications.apply(adapter, arguments);
});
?
我不确定我理解你的问题很好,但这应该确保this
是绑定的,而不是undefined
当你做return getNotifications(dbUser);
- $(this).prop('property') vs. this.property
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- 在另一个函数中使用变量this
- this.router在AngularJS 2中未定义
- reactjs this.refs vs document.getElementById
- JavaScript 中的嵌套函数和 “this” 关键字
- React+Meteor:this.ops返回未定义
- javascript中对象构造函数中的var属性与this.properties
- 函数中this和var之间的区别
- jQuery(this).Pparent().Pparente().Prent().find()在iPad上不起作用
- Understanding Javascript scope with "var that = this&qu
- 定义this.properties或objectName.properties的javascript JSON对象
- Object.prototype using 'this'
- 在JavaScript类型的函数中避免self-this
- 如何使用(this)访问Angular 2 http rxjs catch函数中的对象属性
- Javascript 对象和 this 关键字
- jQuery使用ajax自动完成问题-TypeError:this.source不是函数
- reactjs无法将this.pops传递到react图表列表中
- 为什么在这种情况下,“This”确实充当javascript函数中的私有成员
- 如何确保正确的“this”;Promise.promisify