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

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

问题描述

我正在尝试使用带有 Bluebird 库的 promise 重构我的 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 (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:

未处理的拒绝类型错误:无法读取未定义的属性nano"在 Adapter.getNotifications (/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)

编辑

在user2864740的宝贵意见之后,我注意到错误与一些范围问题有关.那么,为什么在使用 promisify 方法后,该方法不 getNotifications 识别this"环境变量?

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() 方法,或在 adapter 上调用新的 getNotifications 函数(使用 <代码>.call()).您也可以考虑使用 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(…).

请注意,这仍然不起作用.您不能简单地在循环中创建承诺 - 您需要显式地等待它们并从 then 回调中返回一个承诺,否则只会将您返回的 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天全站免登陆