2015-09-10 18 views
8

Tôi đang cố gắng tinh chỉnh máy chủ nodejs của mình bằng lời hứa với thư viện Bluebird, nhưng tôi bị kẹt trong một vấn đề đơn giản.Cách đảm bảo "điều này" chính xác với Promise.promisify?

Sau khi chỉ khiến người dùng từ db của tôi, tôi muốn liệt kê tất cả lớp thông báo liên quan đến thành viên này:

Bad Way (làm việc ...)

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

Elegant Way dự kiến ​​(không hoạt động ...)

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"); 
}); 

Tuy nhiên khi tôi thực thi mã này tôi nhận được lỗi này trong phương pháp getNotification tôi:

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)

EDIT

Sau user2864740`s ý kiến ​​quý báu, tôi nhận thấy rằng các lỗi có liên quan với một số vấn đề phạm vi. Vì vậy, tại sao sau khi sử dụng phương pháp promisify, phương thức dont getNotifications nhận ra biến "env" này?

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); 
    }); 

}; 
+0

Hey, lỗi được tạo bên trong phương thức getNotifications đang được "quảng bá". –

+0

@ user2864740 Một lần nữa, tôi đã chỉnh sửa câu hỏi, tôi nghĩ rằng vấn đề có liên quan với các biến phạm vi ... –

+0

Thử '.call()' ing nó với 'adapter' và' this'. – Amit

Trả lời

6

này chỉ là rất phổ biến problem of calling "unbound" methods.
Bạn có thể vượt qua bối cảnh như một tùy chọn để Promise.promisify để có nó ràng buộc:

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

Ngoài ra, bạn sẽ cần phải .bind() phương pháp, hoặc gọi getNotifications chức năng mới trên adapter (sử dụng .call()). Bạn cũng có thể xem xét sử dụng Promise.promisifyAll(adapater) và sau đó chỉ cần gọi adapter.getNotificationsAsync(…).

Lưu ý rằng thao tác này vẫn không hoạt động. Bạn không thể đơn giản tạo lời hứa trong vòng lặp - bạn cần đợi chúng một cách rõ ràng và trả lại lời hứa từ cuộc gọi lại then, nếu không chỉ giá trị undefined bạn trả lại sẽ được chuyển đến cuộc gọi lại tiếp theo ngay lập tức.

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]); 
}); 

Thay vì Promise.all(users.rows.map(…)), trong Bluebird bạn cũng có thể sử dụng Promise.map(users.rows, …).

+0

Bạn đúng, cảm ơn bạn đã giải thích chi tiết cho câu hỏi này và phương pháp "không liên kết". –

+1

Trong ngữ cảnh Bluebird 3.4.6 bị ràng buộc như thế này: 'Promise.promisify (adapter.getNotifications, {context: adapter}); ' –

+0

@CryptixMaster Cảm ơn, đã cập nhật lên 3.0 tài liệu và mã :-) – Bergi

1

gì về đơn giản

var getNotifications = Promise.promisify(adapter.getNotifications.bind(adapter)); 

hoặc có thể

var getNotifications = Promise.promisify(function() { 
    return adapter.getNotifications.apply(adapter, arguments); 
}); 

?

Tôi không chắc là tôi hiểu vấn đề của bạn tốt, nhưng điều này nên chắc chắn this là ràng buộc và không undefined khi bạn làm return getNotifications(dbUser);

Các vấn đề liên quan