You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by gl...@apache.org on 2021/01/12 13:54:08 UTC

[couchdb-nano] 04/04: convert examples to async/await style

This is an automated email from the ASF dual-hosted git repository.

glynnbird pushed a commit to branch 9.0.2prep
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 0c42c22a617b7af548004ca209c3a358ff7469a9
Author: Glynn Bird <gl...@apache.org>
AuthorDate: Tue Jan 12 09:31:45 2021 +0000

    convert examples to async/await style
---
 README.md | 282 +++++++++++++++++++-------------------------------------------
 1 file changed, 87 insertions(+), 195 deletions(-)

diff --git a/README.md b/README.md
index 5c3b77f..5fc3d69 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ Note the minimum required version of Node.js is 10.
   - [db.fetch(docnames, [params], [callback])](#dbfetchdocnames-params-callback)
   - [db.fetchRevs(docnames, [params], [callback])](#dbfetchrevsdocnames-params-callback)
   - [db.createIndex(indexDef, [callback])](#dbcreateindexindexdef-callback)
-  - [db.changesReader...](#reading-changes-feed)
+  - [db.changesReader](#reading-changes-feed)
 - [Partitioned database functions](#partition-functions)
   - [db.partitionInfo(partitionKey, [callback])](#dbpartitioninfopartitionkey-callback))
   - [db.partitionedList(partitionKey, [params], [callback])](#dbpartitionedlistpartitionkey-params-callback)
@@ -108,7 +108,7 @@ To use `nano` you need to connect it to your CouchDB install, to do that:
 const nano = require('nano')('http://localhost:5984');
 ```
 
-The URL you supply may also contain authentication credentials e.g. `http://admin:mypassword@localhost:5984`.
+> Note: The URL you supply may also contain authentication credentials e.g. `http://admin:mypassword@localhost:5984`.
 
 To create a new database:
 
@@ -180,24 +180,7 @@ async function asyncCall() {
 asyncCall()
 ```
 
-or in the raw Promises-style
-
-```js
-const nano = require('nano')('http://localhost:5984');
-let alice;
-
-nano.db.destroy('alice').then((response) => {
-  return nano.db.create('alice')
-}).then((response) =>  {
-  alice = nano.use('alice')
-  return alice.insert({ happy: true }, 'rabbit')
-}).then((response) => {
-  console.log('you have inserted a document with an _id of rabbit')
-  console.log(response);
-})
-```
-
-If you run either of these examples (after starting CouchDB) you will see:
+Running this example will produce:
 
 ```
 you have inserted a document with an _id of rabbit.
@@ -251,28 +234,21 @@ const db = couch.use('foo');
 
 ### Pool size and open sockets
 
-A very important configuration parameter if you have a high traffic website and are using `nano` is setting up the `pool.size`. By default, the Node.js HTTP global agent (client) has a certain size of active connections that can run simultaneously, while others are kept in a queue. Pooling can be disabled by setting the `agent` property in `requestDefaults` to `false`, or adjust the global pool size using:
+A very important configuration parameter if you have a high traffic website and are using `nano` is the HTTP pool size. By default, the Node.js HTTP global agent has a infinite number of active connections that can run simultaneously. This can be limited to user-defined number (`maxSockets`) of requests that are "in flight", while others are kept in a queue. Here's an example explicitly using the Node.js HTTP agent configured with [custom options](https://nodejs.org/api/http.html#http_ne [...]
 
 ```js
-http.globalAgent.maxSockets = 20;
-```
-
-You can also increase the size in your calling context using `requestDefaults` if this is problematic. Refer to the [request] documentation and examples for further clarification.
-
-Here's an example explicitly using the keep alive agent (installed using `npm install agentkeepalive`), especially useful to limit your open sockets when doing high-volume access to CouchDB on localhost:
+const http = require('http')
+const myagent = new http.Agent({
+  keepAlive: true,
+  maxSockets: 25
+})
 
-```js
-const agentkeepalive = require('agentkeepalive');
-const myagent = new agentkeepalive({
-  maxSockets: 50,
-  maxKeepAliveRequests: 0,
-  maxKeepAliveTime: 30000
+const db = require('nano')({ 
+  url: 'http://localhost:5984/foo',
+  requestDefaults : { 
+    agent : myagent 
+  }
 });
-
-const db = require('nano')(
-  { url: "http://localhost:5984/foo",
-    requestDefaults : { "agent" : myagent }
-  });
 ```
 
 ## TypeScript
@@ -325,9 +301,7 @@ db.insert(p).then((response) => {
 Creates a CouchDB database with the given `name`:
 
 ```js
-nano.db.create('alice').then((body) => {
-  console.log('database alice created!');
-})
+await nano.db.create('alice')
 ```
 
 ### nano.db.get(name, [callback])
@@ -335,9 +309,7 @@ nano.db.create('alice').then((body) => {
 Get information about the database `name`:
 
 ```js
-nano.db.get('alice').then((body) => {
-  console.log(body);
-})
+const info = await nano.db.get('alice')
 ```
 
 ### nano.db.destroy(name, [callback])
@@ -345,9 +317,7 @@ nano.db.get('alice').then((body) => {
 Destroys the database `name`:
 
 ```js
-nano.db.destroy('alice').then((body) => {
-  // database destroyed
-})
+await nano.db.destroy('alice')
 ```
 
 ### nano.db.list([callback])
@@ -355,12 +325,7 @@ nano.db.destroy('alice').then((body) => {
 Lists all the CouchDB databases:
 
 ```js
-nano.db.list().then((body) => {
-  // body is an array
-  body.forEach((db) => {
-    console.log(db);
-  });
-});
+const dblist = await nano.db.list()
 ```
 
 ### nano.db.listAsStream()
@@ -384,10 +349,9 @@ has to exist, add `create_target:true` to `opts` to create it prior to
 replication:
 
 ```js
-nano.db.replicate('alice', 'http://admin:password@otherhost.com:5984/alice',
-                  { create_target:true }).then((body) => {
-  console.log(body);
-});
+const response = await nano.db.replicate('alice', 
+                  'http://admin:password@otherhost.com:5984/alice',
+                  { create_target:true })
 ```
 
 ### nano.db.replication.enable(source, target, [opts], [callback])
@@ -397,10 +361,9 @@ with options `opts`. `target` has to exist, add `create_target:true` to
 `opts` to create it prior to replication. Replication will survive server restarts.
 
 ```js
-nano.db.replication.enable('alice', 'http://admin:password@otherhost.com:5984/alice',
-                  { create_target:true }).then((body) => {
-  console.log(body);
-});
+const response = await nano.db.replication.enable('alice', 
+                  'http://admin:password@otherhost.com:5984/alice',
+                  { create_target:true })
 ```
 
 ### nano.db.replication.query(id, [opts], [callback])
@@ -409,12 +372,10 @@ Queries the state of replication using the new CouchDB API. The `id` comes from
 given by the call to `replication.enable`:
 
 ```js
-nano.db.replication.enable('alice', 'http://admin:password@otherhost.com:5984/alice',
-                   { create_target:true }).then((body) => {
-  return nano.db.replication.query(body.id);
-}).then((response) => {
-  console.log(response);
-});
+const r = await nano.db.replication.enable('alice', 
+                  'http://admin:password@otherhost.com:5984/alice',
+                   { create_target:true })
+const q = await nano.db.replication.query(r.id)
 ```
 
 ### nano.db.replication.disable(id, [opts], [callback])
@@ -423,12 +384,10 @@ Disables replication using the new CouchDB API. The `id` comes from the response
 by the call to `replication.enable`:
 
 ```js
-nano.db.replication.enable('alice', 'http://admin:password@otherhost.com:5984/alice',
-                   { create_target:true }).then((body) => {
-  return nano.db.replication.disable(body.id);
-}).then((response) => {
-  console.log(response);
-});
+const r = await nano.db.replication.enable('alice', 
+                   'http://admin:password@otherhost.com:5984/alice',
+                   { create_target:true })
+await nano.db.replication.disable(r.id);
 ```
 
 ### nano.db.changes(name, [params], [callback])
@@ -437,9 +396,7 @@ Asks for the changes feed of `name`, `params` contains additions
 to the query string.
 
 ```js
-nano.db.changes('alice').then((body) => {
-  console.log(body);
-});
+const c = await nano.db.changes('alice')
 ```
 
 ### nano.db.changesAsStream(name, [params])
@@ -455,9 +412,7 @@ nano.db.changes('alice').pipe(process.stdout);
 Gets database information:
 
 ```js
-nano.db.info().then((body) => {
-  console.log('got database info', body);
-});
+const info = await nano.db.info()
 ```
 
 ### nano.use(name)
@@ -466,11 +421,11 @@ Returns a database object that allows you to perform operations against that dat
 
 ```js
 const alice = nano.use('alice');
-alice.insert({ happy: true }, 'rabbit').then((body) => {
-  // do something
-});
+await alice.insert({ happy: true }, 'rabbit')
 ```
 
+The database object can be used to access the [Document Functions](#document-functions).
+
 ### nano.db.use(name)
 
 Alias for `nano.use`
@@ -532,27 +487,21 @@ Inserts `doc` in the database with optional `params`. If params is a string, it'
 
 ```js
 const alice = nano.use('alice');
-alice.insert({ happy: true }, 'rabbit').then((body) => {
-  console.log(body);
-});
+const response = await alice.insert({ happy: true }, 'rabbit')
 ```
 
 The `insert` function can also be used with the method signature `db.insert(doc,[callback])`, where the `doc` contains the `_id` field e.g.
 
 ```js
 const alice = nano.use('alice')
-alice.insert({ _id: 'myid', happy: true }).then((body) => {
-  console.log(body)
-})
+const response alice.insert({ _id: 'myid', happy: true })
 ```
 
 and also used to update an existing document, by including the `_rev` token in the document being saved:
 
 ```js
 const alice = nano.use('alice')
-alice.insert({ _id: 'myid', _rev: '1-23202479633c2b380f79507a776743d5', happy: false }).then((body) => {
-  console.log(body)
-})
+const response = await alice.insert({ _id: 'myid', _rev: '1-23202479633c2b380f79507a776743d5', happy: false })
 ```
 
 ### db.destroy(docname, rev, [callback])
@@ -560,9 +509,7 @@ alice.insert({ _id: 'myid', _rev: '1-23202479633c2b380f79507a776743d5', happy: f
 Removes a document from CouchDB whose `_id` is `docname` and who's revision is `_rev`:
 
 ```js
-alice.destroy('rabbit', '3-66c01cdf99e84c83a9b3fe65b88db8c0').then((body) => {
-  console.log(body);
-});
+const response = await alice.destroy('rabbit', '3-66c01cdf99e84c83a9b3fe65b88db8c0')
 ```
 
 ### db.get(docname, [params], [callback])
@@ -570,17 +517,13 @@ alice.destroy('rabbit', '3-66c01cdf99e84c83a9b3fe65b88db8c0').then((body) => {
 Gets a document from CouchDB whose `_id` is `docname`:
 
 ```js
-alice.get('rabbit').then((body) => {
-  console.log(body);
-});
+const doc = await alice.get('rabbit')
 ```
 
 or with optional query string `params`:
 
 ```js
-alice.get('rabbit', { revs_info: true }).then((body) => {
-  console.log(body);
-});
+const doc = await alice.get('rabbit', { revs_info: true })
 ```
 
 ### db.head(docname, [callback])
@@ -588,9 +531,7 @@ alice.get('rabbit', { revs_info: true }).then((body) => {
 Same as `get` but lightweight version that returns headers only:
 
 ```js
-alice.head('rabbit').then((headers) => {
-  console.log(headers);
-});
+const headers = await alice.head('rabbit')
 ```
 
 *Note:* if you call `alice.head` in the callback style, the headers are returned to you as the third argument of the callback function.
@@ -605,9 +546,7 @@ const documents = [
   { a:1, b:2 },
   { _id: 'tiger', striped: true}
 ];
-alice.bulk({docs:documents}).then((body) => {
-  console.log(body);
-});
+const response = await alice.bulk({ docs: documents })
 ```
 
 ### db.list([params], [callback])
@@ -615,22 +554,16 @@ alice.bulk({docs:documents}).then((body) => {
 List all the docs in the database .
 
 ```js
-alice.list().then((body) => {
-  body.rows.forEach((doc) => {
-    console.log(doc);
-  });
+const doclist = await alice.list().then((body)
+doclist.rows.forEach((doc) => {
+  console.log(doc);
 });
 ```
 
 or with optional query string additions `params`:
 
 ```js
-alice.list({include_docs: true}).then((body) => {
-  body.rows.forEach((doc) => {
-    // output each document's body
-    console.log(doc.doc);
-  });
-});
+const doclist = await alice.list({include_docs: true})
 ```
 
 ### db.listAsStream([params])
@@ -652,9 +585,7 @@ to `true`.
 
 ```js
 const keys = ['tiger', 'zebra', 'donkey'];
-alice.fetch({keys: keys}).then((data) => {
-  console.log(data);
-});
+const datat = await alice.fetch({keys: keys})
 ```
 
 ### db.fetchRevs(docnames, [params], [callback])
@@ -676,9 +607,7 @@ const indexDef = {
   index: { fields: ['foo'] },
   name: 'fooindex'
 };
-alice.createIndex(indexDef).then((result) => {
-  console.log(result);
-});
+const response = await alice.createIndex(indexDef)
 ```
 
 ## Reading Changes Feed
@@ -996,9 +925,7 @@ const fs = require('fs');
 
 fs.readFile('rabbit.png', (err, data) => {
   if (!err) {
-    alice.multipart.insert({ foo: 'bar' }, [{name: 'rabbit.png', data: data, content_type: 'image/png'}], 'mydoc').then((body) => {
-      console.log(body);
-    });
+    await alice.multipart.insert({ foo: 'bar' }, [{name: 'rabbit.png', data: data, content_type: 'image/png'}], 'mydoc')
   }
 });
 ```
@@ -1009,9 +936,7 @@ Get `docname` together with its attachments via `multipart/related` request with
  [doc](http://wiki.apache.org/couchdb/HTTP_Document_API#Getting_Attachments_With_a_Document) for more details. The multipart response body is a `Buffer`.
 
 ```js
-alice.multipart.get('rabbit').then((buffer) => {
-  console.log(buffer.toString());
-});
+const response = await alice.multipart.get('rabbit')
 ```
 
 ## Attachments functions
@@ -1027,10 +952,11 @@ const fs = require('fs');
 
 fs.readFile('rabbit.png', (err, data) => {
   if (!err) {
-    alice.attachment.insert('rabbit', 'rabbit.png', data, 'image/png',
-      { rev: '12-150985a725ec88be471921a54ce91452' }).then((body) => {
-        console.log(body);
-    });
+    await alice.attachment.insert('rabbit', 
+      'rabbit.png', 
+      data, 
+      'image/png',
+      { rev: '12-150985a725ec88be471921a54ce91452' })
   }
 });
 ```
@@ -1048,18 +974,16 @@ Get `docname`'s attachment `attname` with optional query string additions
 ```js
 const fs = require('fs');
 
-alice.attachment.get('rabbit', 'rabbit.png').then((body) => {
-  fs.writeFile('rabbit.png', body);
-});
+const body = await alice.attachment.get('rabbit', 'rabbit.png')
+fs.writeFile('rabbit.png', body)
 ```
 
 ### db.attachment.getAsStream(docname, attname, [params])
 
 ```js
 const fs = require('fs');
-
 alice.attachment.getAsStream('rabbit', 'rabbit.png')
-  .on('error', (e) => console.error('error', e))
+  .on('error', e => console.error)
   .pipe(fs.createWriteStream('rabbit.png'));
 ```
 
@@ -1070,10 +994,7 @@ alice.attachment.getAsStream('rabbit', 'rabbit.png')
 Destroy attachment `attname` of `docname`'s revision `rev`.
 
 ```js
-alice.attachment.destroy('rabbit', 'rabbit.png',
-    {rev: '1-4701d73a08ce5c2f2983bf7c9ffd3320'}).then((body) => {
-       console.log(body);
-});
+const response = await alice.attachment.destroy('rabbit', 'rabbit.png', {rev: '1-4701d73a08ce5c2f2983bf7c9ffd3320'})
 ```
 
 ## Views and design functions
@@ -1084,44 +1005,26 @@ Calls a view of the specified `designname` with optional query string `params`.
 `{ keys: ['key1', 'key2', 'key_n'] }`, as `params`.
 
 ```js
-alice.view('characters', 'happy_ones', {
-  'key': 'Tea Party',
-  'include_docs': true
-}).then((body) => {
-  body.rows.forEach((doc) => {
-    console.log(doc.value);
-  });
-});
+const body = await alice.view('characters', 'happy_ones', { key: 'Tea Party', include_docs: true })
+body.rows.forEach((doc) => {
+  console.log(doc.value)
+})
 ```
 
 or
 
 ```js
-alice.view('characters', 'soldiers', {
-  'keys': ['Hearts', 'Clubs']
-}).then((body) => {
-  body.rows.forEach((doc) => {
-    console.log(doc.value);
-  });
-});
+const body = await alice.view('characters', 'soldiers', { keys: ['Hearts', 'Clubs'] })
 ```
 
 When `params` is not supplied, or no keys are specified, it will simply return all documents in the view:
 
 ```js
-alice.view('characters', 'happy_ones').then((body) => {
-  body.rows.forEach((doc) => {
-    console.log(doc.value);
-  });
-});
+const body = await alice.view('characters', 'happy_ones')
 ```
 
 ```js
-alice.view('characters', 'happy_ones', { include_docs: true }).then((body) => {
-  body.rows.forEach((doc) => {
-    console.log(doc.value);
-  });
-});
+const body = alice.view('characters', 'happy_ones', { include_docs: true })
 ```
 
 ### db.viewAsStream(designname, viewname, [params])
@@ -1139,9 +1042,7 @@ alice.viewAsStream('characters', 'happy_ones', {reduce: false})
 Calls a list function fed by the given view from the specified design document.
 
 ```js
-alice.viewWithList('characters', 'happy_ones', 'my_list').then((body) => {
-  console.log(body);
-});
+const body = await alice.viewWithList('characters', 'happy_ones', 'my_list')
 ```
 
 ### db.viewWithListAsStream(designname, viewname, listname, [params], [callback])
@@ -1149,9 +1050,9 @@ alice.viewWithList('characters', 'happy_ones', 'my_list').then((body) => {
 Calls a list function fed by the given view from the specified design document as a stream.
 
 ```js
-alice.viewWithListAsStream('characters', 'happy_ones', 'my_list').then((body) => {
-  console.log(body);
-});
+alice.viewWithListAsStream('characters', 'happy_ones', 'my_list')
+  .on('error', (e) => console.error('error', e))
+  .pipe(process.stdout);
 ```
 
 ### db.show(designname, showname, doc_id, [params], [callback])
@@ -1160,9 +1061,7 @@ Calls a show function from the specified design for the document specified by do
 optional query string additions `params`.
 
 ```js
-alice.show('characters', 'format_doc', '3621898430').then((doc) => {
-  console.log(doc);
-});
+const doc = await alice.show('characters', 'format_doc', '3621898430')
 ```
 
 Take a look at the [couchdb wiki](http://wiki.apache.org/CouchDB/Formatting_with_Show_and_List#Showing_Documents)
@@ -1173,10 +1072,7 @@ for possible query paramaters and more information on show functions.
 Calls the design's update function with the specified doc in input.
 
 ```js
-db.atomic("update", "inplace", "foobar",
-{field: "foo", value: "bar"}).then((response) => {
-  console.log(response);
-});
+const response = await db.atomic('update', 'inplace', 'foobar', {field: 'foo', value: 'bar'})
 ```
 
 Note that the data is sent in the body of the request.
@@ -1185,13 +1081,12 @@ An example update handler follows:
 ```js
 "updates": {
   "in-place" : "function(doc, req) {
-      var request_body = JSON.parse(req.body);
-
-      var field = request_body.field;
-      var value = request_body.value;
-      var message = 'set ' + field + ' to ' + value;
-      doc[field] = value;
-      return [doc, message];
+      var request_body = JSON.parse(req.body)
+      var field = request_body.field
+      var value = request_body.value
+      var message = 'set ' + field + ' to ' + value
+      doc[field] = value
+      return [doc, message]
   }"
 }
 ```
@@ -1201,18 +1096,14 @@ An example update handler follows:
 Calls a view of the specified design with optional query string additions `params`.
 
 ```js
-alice.search('characters', 'happy_ones', { q: 'cat' }).then((doc) => {
-  console.log(doc);
-});
+const response = await alice.search('characters', 'happy_ones', { q: 'cat' })
 ```
 
 or
 
 ```js
 const drilldown = [['author', 'Dickens']['publisher','Penguin']]
-alice.search('inventory', 'books', { q: '*:*', drilldown: drilldown }).then((doc) => {
-  console.log(doc);
-});
+const response = await alice.search('inventory', 'books', { q: '*:*', drilldown: drilldown })
 ```
 
 Check out the tests for a fully functioning example.
@@ -1239,9 +1130,7 @@ const q = {
   fields: [ "name", "age", "tags", "url" ],
   limit:50
 };
-alice.find(q).then((doc) => {
-  console.log(doc);
-});
+const response = await alice.find(q)
 ```
 
 ### db.findAsStream(selector)
@@ -1278,7 +1167,10 @@ const username = 'user'
 const userpass = 'pass'
 const db = nano.db.use('mydb')
 
+// authenticate
 await nano.auth(username, userpass)
+
+// requests from now on are authenticated
 const doc = await db.get('mydoc')
 console.log(doc)
 ```