2013-07-04 7 views
31

Tôi đang sử dụng thiên thạch 0.6.4.Meteor.methods trả về undefined

Meteor.methods({ 
    random: function(top){ 
    var random = Math.floor((Math.random()*(top+1))); 
    return random; 
    } 
}); 

Nó trả về undefined bất cứ khi nào tôi thực hiện

Meteor.call('random', 10); 

Bất kỳ ý tưởng làm thế nào tôi có thể vượt qua điều này?

Trả lời

57

Đây là một hành vi hoàn toàn bình thường: Phương pháp máy chủ gọi trong Meteor là documented là không đồng bộ:

Trên client, nếu bạn không vượt qua một callback và bạn không phải là bên trong vẫn còn sơ khai, cuộc gọi sẽ trở lại không xác định, và bạn sẽ không có cách nào để lấy giá trị trả về của phương thức.

Điều này có nghĩa là khi bạn yêu cầu phương thức Meteor.call để thực thi từ xa trên máy chủ, cuộc gọi phương thức cục bộ không bị chặn và trả về undefined ngay lập tức. Khi phương pháp này đã được gọi là trên máy chủ nó sẽ gửi kết quả không đồng bộ cho khách hàng, vì vậy bạn nên lấy nó bằng cách sử dụng mô hình callback:

Meteor.call("myMethod", arguments..., function(error, result){ 
    if(error){ 
    console.log(error.reason); 
    return; 
    } 
    // do something with result 
}); 

Chức năng gọi lại ẩn danh sẽ được gọi trên máy khách càng sớm càng kết quả của phương thức máy chủ được gửi lại cho máy khách.

Có một tính năng tinh tế khác trong Meteor làm mất hiệu lực những gì tôi vừa nói: độ trễ bù và phương thức khai báo. Trong trường hợp cuộc gọi phương thức máy chủ có thể được mô phỏng đúng cách trong máy khách và do đó được thực thi ngay lập tức mà không có một chuyến đi vòng tới máy chủ, bạn có thể xác định cái được gọi là phương thức (hoặc mô phỏng). Một trường hợp sử dụng phổ biến cho hành vi này được chèn ngay lập tức trong cơ sở dữ liệu cục bộ (client side replication subset) một số nội dung người dùng vừa được đăng (một bình luận dưới một bài viết blog): tất cả các dữ liệu cần thiết và logic có sẵn và nó có ý nghĩa để mô phỏng chèn phía máy chủ. Điều xảy ra tiếp theo là người dùng thấy trang web được cập nhật ngay sau khi gửi nội dung của mình ngay cả khi máy chủ chưa nhận ra những thay đổi này. (đây là một ví dụ về cách bù trễ độ trễ được thực hiện trong Meteor). Tất nhiên máy chủ có các từ cuối cùng về những gì cuối cùng được chèn vào trong cơ sở dữ liệu, điều này có nghĩa là khi phương thức song phương phía máy chủ được thực thi, hành động của nó sẽ được ưu tiên và thay thế những gì được chèn vào cơ sở dữ liệu cục bộ.

Để xác định phương thức như vậy, bạn chỉ cần xác định cùng tên phương thức máy chủ trên mã máy khách. Nếu khai báo phương thức được định nghĩa trong mã chia sẻ (vận chuyển cả client và server), bạn có thể kiểm tra xem các cuộc gọi phương pháp thực sự là một mô phỏng bằng cách kiểm tra isSimulation tài sản:

Meteor.methods({ 
    myMethod: function(arguments...){ 
     if(this.isSimulation){ 
      // called from the client 
     } 
    } 
}); 

CẬP NHẬT 26/11/2014: @ steph643 nhận xét về cách phần cuối cùng của câu trả lời trước của tôi thực sự sai, đây là một sự điều chỉnh.

Lưu ý rằng trên các cuộc gọi phương thức máy chủ luôn có thể được gọi bằng cú pháp đồng bộ vì môi trường máy chủ cung cấp đầy đủ cơ chế chặn (sợi).

Trên client tuy nhiên, nếu bạn quay lại một cái gì đó từ một sơ khai phương pháp, nó có thể được thực hiện đồng bộ chỉ khi bạn đang ở trong cuống nhau và bạn có thể lấy kết quả trong một cách đồng bộ, tức là

Meteor.methods({ 
    intermediateMethod: function(){ 
    return " WORLD"; 
    }, 
    method: function(){ 
    var result = "HELLO"; 
    result += intermediateResult; 
    var intermediateResult = Meteor.call("intermediateMethod"); 
    return result; 
    } 
}); 

Hành vi này hơi lạ khi xem các hoạt động thu thập Mongo (chèn/cập nhật/xóa) được thực hiện như các phương thức Meteor và các phiên bản máy khách của chúng đang triển khai thực hiện các lệnh hợp lệ (sửa đổi tập con cơ sở dữ liệu cục bộ được nhân bản tối thiểu) có thể được thực thi đồng bộ.

+0

Xin cảm ơn, đã phải xoay sở xung quanh nhưng điều này đã giúp ích rất nhiều. http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

"Nếu bạn trả lại một cái gì đó từ một cuống phương pháp, nó có thể được thực hiện đồng bộ trên máy khách và bạn có thể lấy kết quả theo cách thông thường". Đây không phải là sự thật. Một cuộc gọi phương thức được phát hành từ máy khách trả về 'không xác định' cho dù có còn sơ khai hay không. Cf. doc: "Trên máy khách, nếu bạn không vượt qua một cuộc gọi lại và bạn không ở trong một thư mục [nghĩa là bạn không gọi phương thức từ bên trong một thư khác], cuộc gọi sẽ trả về không xác định và bạn sẽ không có cách nào để nhận giá trị trả về của phương thức ". Điều này áp dụng cho dù có một stub được gắn vào phương thức hay không. – steph643

+0

Cảm ơn bạn đã chỉ ra điều này, tôi cũng đang theo dõi chủ đề của bạn trên thiên thạch. Tôi trích dẫn các tài liệu trong câu trả lời của tôi và họ rõ ràng nói rằng thực thi đồng bộ phía máy khách của phương thức khai thác chỉ có thể diễn ra trong một cuộc gọi phương thức khác, nhưng nó có ý nghĩa rất ít vì vậy tôi giả định ngược lại. – saimeunt