如何确保正确的“这个”与Promise.promisify? [英] How to ensure correct "this" with Promise.promisify?

查看:403
本文介绍了如何确保正确的“这个”与Promise.promisify?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用与Bluebird库的promises重构我的nodejs服务器,但我遇到了一个简单的问题。

I am trying to refactory my nodejs server using promises with Bluebird library, but I am stuck in a simple problem.

之后从我的数据库中获取用户,我想列出与此用户关联的所有通知类:

After to get the users from my db, I want to list all notification class associated with this user:

Bad Way(正在工作......)

Bad Way (working...)

adapter.getUsers(function(users){
    users.rows.forEach(function(item){
        user = item.username;
        adapter.getNotifications(user, function(notificationList){
            console.log(notificationList);
        })
    });
});

优雅的暂定方式(不工作......)

Elegant Tentative Way (not working...)

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方法中出现此错误:

However when I execute this code I get this error inside my getNotification method:


未处理的拒绝TypeError:无法在Adapter.getNotifications上读取未定义
的属性'nano'(/ Users / DaniloOliveira / Workspace / sigalei-api / api / tools / couchdb-adapter.js:387:30)在tryCatcher上的
(/Users/DaniloOliveira/Workspace/sigalei-api/node_modules/bluebird/js/main/util.js:26:23)

Unhandled rejection TypeError: Cannot read property 'nano' of undefined at Adapter.getNotifications (/Users/DaniloOliveira/Workspace/sigalei-api/api/tools/couchdb-adapter.js:387:30) at tryCatcher (/Users/DaniloOliveira/Workspace/sigalei-api/node_modules/bluebird/js/main/util.js:26:23)

编辑


在用户2864740的宝贵评论之后,我注意到了错误与某些范围问题有关。那么,为什么在使用promisify方法之后,方法dont getNotifications会识别thisenv变量?

EDIT

After the user2864740`s precious comments, I noticed that the error is related with some scope problem. So, why after to use promisify method, the method dont getNotifications recognize the "this" env variable?

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 让它绑定:

This is just the very common problem of calling "unbound" methods.
You can pass the context as an option to Promise.promisify to have it bound:

var getNotifications = Promise.promisify(adapter.getNotifications, {context: adapter});

或者,你需要 .bind()方法,或在适配器上调用新的 getNotifications 函数(使用。呼叫())。您也可以考虑使用 Promise.promisifyAll(adapater),然后只需调用 adapter.getNotificationsAsync(...)

Alternatively, you'd need to .bind() the method, or call the new getNotifications function on the adapter (using .call()). You might also consider using Promise.promisifyAll(adapater) and then just calling adapter.getNotificationsAsync(…).

请注意,这仍然无效。你不能简单地在循环中创建promises - 你需要显式地等待它们并从然后回调返回一个promise,否则只是 undefined 您返回的值将立即传递给下一个回调。

Notice that this still doesn't work. You cannot simply create promises in a loop - you need to await them explicitly and return a promise from the then callback, otherwise just the undefined value you returned will be passed to the next callback immediately.

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.all(users.rows.map(...)) ,在Bluebird中你也可以使用 Promise.map(users.rows,...)

Instead of Promise.all(users.rows.map(…)), in Bluebird you can also use Promise.map(users.rows, …).

这篇关于如何确保正确的“这个”与Promise.promisify?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆