MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Ứng dụng Node / Express đơn giản, cách lập trình chức năng (Làm thế nào để xử lý các hiệu ứng phụ trong JavaScript?)

Bạn sẽ không thể tránh hoàn toàn các tác dụng phụ nhưng bạn có thể nỗ lực để loại bỏ chúng một cách tối đa nếu có thể.

Ví dụ, khung Express vốn dĩ là bắt buộc. Bạn chạy các hàm như res.send() hoàn toàn cho các tác dụng phụ của chúng (bạn thậm chí không quan tâm đến giá trị trả lại của nó hầu hết thời gian).

Bạn có thể làm gì (ngoài việc sử dụng const cho tất cả các khai báo của bạn, sử dụng Immutable.js cấu trúc dữ liệu, Ramda , viết tất cả các hàm dưới dạng const fun = arg => expression; thay vì const fun = (arg) => { statement; statement; }; v.v.) sẽ là tạo ra một chút trừu tượng về cách Express thường hoạt động.

Ví dụ:bạn có thể tạo các hàm sử dụng req dưới dạng tham số và trả về một đối tượng có chứa trạng thái phản hồi, tiêu đề và một luồng được chuyển thành phần nội dung. Các hàm đó có thể là các hàm thuần túy theo nghĩa là giá trị trả về của chúng chỉ phụ thuộc vào đối số của chúng (đối tượng yêu cầu) nhưng bạn vẫn sẽ cần một số trình bao bọc để thực sự gửi phản hồi bằng cách sử dụng API bắt buộc vốn có của Express. Nó có thể không tầm thường nhưng nó có thể làm được.

Ví dụ, hãy xem hàm này lấy body làm đối tượng để gửi dưới dạng json:

const wrap = f => (req, res) => {
  const { status = 200, headers = {}, body = {} } = f(req);
  res.status(status).set(headers).json(body);
};

Nó có thể được sử dụng để tạo các trình xử lý tuyến đường như thế này:

app.get('/sum/:x/:y', wrap(req => ({
  headers: { 'Foo': 'Bar' },
  body: { result: +req.params.x + +req.params.y },
})));

bằng cách sử dụng một hàm trả về một biểu thức duy nhất không có tác dụng phụ.

Toàn bộ ví dụ:

const app = require('express')();

const wrap = f => (req, res) => {
  const { status = 200, headers = {}, body = {} } = f(req);
  res.status(status).set(headers).json(body);
};

app.get('/sum/:x/:y', wrap(req => ({
  headers: { 'Foo': 'Bar' },
  body: { result: +req.params.x + +req.params.y },
})));

app.listen(4444);

Kiểm tra phản hồi:

$ curl localhost:4444/sum/2/4 -v
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 4444 (#0)
> GET /sum/2/4 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:4444
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Foo: Bar
< Content-Type: application/json; charset=utf-8
< Content-Length: 12
< ETag: W/"c-Up02vIPchuYz06aaEYNjufz5tpQ"
< Date: Wed, 19 Jul 2017 15:14:37 GMT
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
{"result":6}

Tất nhiên đây chỉ là một ý tưởng cơ bản. Bạn có thể tạo wrap() hàm chấp nhận các lời hứa cho giá trị trả về của các hàm đối với các tùy chọn không đồng bộ, nhưng sau đó nó được cho là không có tác dụng phụ như vậy:

const wrap = f => async (req, res) => {
  const { status = 200, headers = {}, body = {} } = await f(req);
  res.status(status).set(headers).json(body);
};

và một trình xử lý:

const delay = (t, v) => new Promise(resolve => setTimeout(() => resolve(v), t));

app.get('/sum/:x/:y', wrap(req =>
  delay(1000, +req.params.x + +req.params.y).then(result => ({
    headers: { 'Foo': 'Bar' },
    body: { result },
  }))));

Tôi đã sử dụng .then() thay vì async / await trong chính trình xử lý để làm cho nó trông có chức năng hơn, nhưng nó có thể được viết là:

app.get('/sum/:x/:y', wrap(async req => ({
  headers: { 'Foo': 'Bar' },
  body: { result: await delay(1000, +req.params.x + +req.params.y) },
})));

Nó có thể trở nên phổ biến hơn nữa nếu hàm là đối số của wrap sẽ là một trình tạo mà thay vì chỉ mang lại các lời hứa sẽ giải quyết (giống như các coroutines dựa trên trình tạo thường làm), nó sẽ mang lại hoặc là các hứa sẽ phân giải hoặc chucks để truyền trực tuyến, với một số gói để phân biệt hai điều này. Đây chỉ là một ý tưởng cơ bản nhưng nó có thể được mở rộng hơn nữa.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB trên máy Windows 7:Không thể thực hiện kết nối

  2. đối sánh khung tổng hợp mongodb bằng các tài liệu lồng nhau

  3. làm thế nào để lập chỉ mục tên người dùng trong mongo với phân biệt chữ hoa chữ thường?

  4. MongoDB giải pháp cho tài liệu có kích thước trên 16mb?

  5. Mongoose, mảng vị trí chỉ mục