异步等待样式调用适用于 nano.db.insert 但不适用于 nano.db.list

Async Await style call working for nano.db.insert but not for nano.db.list

我正在使用 https://github.com/apache/couchdb-nano 与我的 nodeJS 项目中的 couchdb 实例进行交互。

const nano = = require('nano')('http://127.0.0.1:5984');
const eventsDb = nano.db.use('events');
const savedEvent = await eventsDb.insert({title: 'ABC'});
console.log('savedEvent:');
console.log(savedEvent.body);

以上有效但以下无效(即记录未定义):

const databases = await nano.db.list();
console.log(databases.body);
console.log(databases.rows);

并且下面打印了一条很长的轨迹:

const databases = await nano.db.list();
console.log(databases);

上面的最后一个打印如下:

Request {
  _events: [Object: null prototype] { pipe: [Function] },
  _eventsCount: 1,
  _maxListeners: undefined,
  method: 'GET',
  headers:
   { 'content-type': 'application/json',
     accept: 'application/json',
     host: '127.0.0.1:5984' },
  uri:
   Url {
     protocol: 'http:',
     slashes: true,
     auth: null,
     host: '127.0.0.1:5984',
     port: '5984',
     hostname: '127.0.0.1',
     hash: null,
     search: null,
     query: null,
     pathname: '/_all_dbs',
     path: '/_all_dbs',
     href: 'http://127.0.0.1:5984/_all_dbs' },
  readable: true,
  writable: true,
  explicitMethod: true,
  _qs:
   Querystring {
     request: [Circular],
     lib:
      { formats: [Object], parse: [Function], stringify: [Function] },
     useQuerystring: undefined,
     parseOptions: {},
     stringifyOptions: {} },
  _auth:
   Auth {
     request: [Circular],
     hasAuth: false,
     sentAuth: false,
     bearerToken: null,
     user: null,
     pass: null },
  _oauth: OAuth { request: [Circular], params: null },
  _multipart:
   Multipart {
     request: [Circular],
     boundary: '85e773c9-18a7-4dee-8564-776339438318',
     chunked: false,
     body: null },
  _redirect:
   Redirect {
     request: [Circular],
     followRedirect: true,
     followRedirects: true,
     followAllRedirects: false,
     followOriginalHttpMethod: false,
     allowRedirect: [Function],
     maxRedirects: 10,
     redirects: [],
     redirectsFollowed: 0,
     removeRefererHeader: false },
  _tunnel:
   Tunnel {
     request: [Circular],
     proxyHeaderWhiteList:
      [ 'accept',
        'accept-charset',
        'accept-encoding',
        'accept-language',
        'accept-ranges',
        'cache-control',
        'content-encoding',
        'content-language',
        'content-location',
        'content-md5',
        'content-range',
        'content-type',
        'connection',
        'date',
        'expect',
        'max-forwards',
        'pragma',
        'referer',
        'te',
        'user-agent',
        'via' ],
     proxyHeaderExclusiveList: [] },
  setHeader: [Function],
  hasHeader: [Function],
  getHeader: [Function],
  removeHeader: [Function],
  localAddress: undefined,
  pool: {},
  dests: [],
  __isRequestRequest: true,
  proxy: null,
  tunnel: false,
  setHost: true,
  originalCookieHeader: undefined,
  _disableCookies: true,
  _jar: false,
  port: '5984',
  host: '127.0.0.1',
  path: '/_all_dbs',
  httpModule:
   { _connectionListener: [Function: connectionListener],
     METHODS:
      [ 'ACL',
        'BIND',
        'CHECKOUT',
        'CONNECT',
        'COPY',
        'DELETE',
        'GET',
        'HEAD',
        'LINK',
        'LOCK',
        'M-SEARCH',
        'MERGE',
        'MKACTIVITY',
        'MKCALENDAR',
        'MKCOL',
        'MOVE',
        'NOTIFY',
        'OPTIONS',
        'PATCH',
        'POST',
        'PROPFIND',
        'PROPPATCH',
        'PURGE',
        'PUT',
        'REBIND',
        'REPORT',
        'SEARCH',
        'SOURCE',
        'SUBSCRIBE',
        'TRACE',
        'UNBIND',
        'UNLINK',
        'UNLOCK',
        'UNSUBSCRIBE' ],
     STATUS_CODES:
      { '100': 'Continue',
        '101': 'Switching Protocols',
        '102': 'Processing',
        '103': 'Early Hints',
        '200': 'OK',
        '201': 'Created',
        '202': 'Accepted',
        '203': 'Non-Authoritative Information',
        '204': 'No Content',
        '205': 'Reset Content',
        '206': 'Partial Content',
        '207': 'Multi-Status',
        '208': 'Already Reported',
        '226': 'IM Used',
        '300': 'Multiple Choices',
        '301': 'Moved Permanently',
        '302': 'Found',
        '303': 'See Other',
        '304': 'Not Modified',
        '305': 'Use Proxy',
        '307': 'Temporary Redirect',
        '308': 'Permanent Redirect',
        '400': 'Bad Request',
        '401': 'Unauthorized',
        '402': 'Payment Required',
        '403': 'Forbidden',
        '404': 'Not Found',
        '405': 'Method Not Allowed',
        '406': 'Not Acceptable',
        '407': 'Proxy Authentication Required',
        '408': 'Request Timeout',
        '409': 'Conflict',
        '410': 'Gone',
        '411': 'Length Required',
        '412': 'Precondition Failed',
        '413': 'Payload Too Large',
        '414': 'URI Too Long',
        '415': 'Unsupported Media Type',
        '416': 'Range Not Satisfiable',
        '417': 'Expectation Failed',
        '418': 'I\'m a Teapot',
        '421': 'Misdirected Request',
        '422': 'Unprocessable Entity',
        '423': 'Locked',
        '424': 'Failed Dependency',
        '425': 'Unordered Collection',
        '426': 'Upgrade Required',
        '428': 'Precondition Required',
        '429': 'Too Many Requests',
        '431': 'Request Header Fields Too Large',
        '451': 'Unavailable For Legal Reasons',
        '500': 'Internal Server Error',
        '501': 'Not Implemented',
        '502': 'Bad Gateway',
        '503': 'Service Unavailable',
        '504': 'Gateway Timeout',
        '505': 'HTTP Version Not Supported',
        '506': 'Variant Also Negotiates',
        '507': 'Insufficient Storage',
        '508': 'Loop Detected',
        '509': 'Bandwidth Limit Exceeded',
        '510': 'Not Extended',
        '511': 'Network Authentication Required' },
     Agent:
      { [Function: Agent] super_: [Function], defaultMaxSockets: Infinity },
     ClientRequest: { [Function: ClientRequest] super_: [Function] },
     globalAgent:
      Agent {
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 80,
        protocol: 'http:',
        options: [Object],
        requests: {},
        sockets: {},
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256 },
     IncomingMessage: { [Function: IncomingMessage] super_: [Function] },
     OutgoingMessage: { [Function: OutgoingMessage] super_: [Function] },
     Server: { [Function: Server] super_: [Function] },
     ServerResponse: { [Function: ServerResponse] super_: [Function] },
     createServer: [Function: createServer],
     get: [Function: get],
     request: [Function: request],
     maxHeaderSize: [Getter] },
  agentClass:
   { [Function: Agent]
     super_:
      { [Function: EventEmitter]
        EventEmitter: [Circular],
        usingDomains: false,
        defaultMaxListeners: [Getter/Setter],
        init: [Function],
        listenerCount: [Function] },
     defaultMaxSockets: Infinity },
  agent:
   Agent {
     _events: [Object: null prototype] { free: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     defaultPort: 80,
     protocol: 'http:',
     options: { path: null },
     requests: {},
     sockets: {},
     freeSockets: {},
     keepAliveMsecs: 1000,
     keepAlive: false,
     maxSockets: Infinity,
     maxFreeSockets: 256 } }

有人能帮忙吗?所有 nano api(s) 都以 async/await 风格工作吗?

您不能以这种方式使用 await,因为 await 只能在异步函数内部工作。尝试以下操作:

async function getDatabases() {
  const databases = await nano.db.list();
  console.log(databases.body);
  console.log(databases.rows);
}
getDatabases();

查看有关 async/await 的教程以更加熟悉 async/await tutorial

最后的堆栈跟踪告诉我您正在 databases 变量中接收到一个请求对象。这是 Nano 7.0.0 之前的默认行为。

如果您使用最新的 Nano(撰写本文时为 v8.0.1),那么大多数 Nano 函数 return Promise 而不是 Request 对象 - 这将使您的 async/await 代码正常工作也就是说,您的变量 databases 将在 Promise 解析时接收 HTTP 请求的主体。

为确保您拥有最新的 Nano,请使用 npm install nano 或修改项目的 package.json 文件以确保请求的版本号在 运行 npm install 之前是最新的。