【问题标题】:Async Await style call working for nano.db.insert but not for nano.db.list异步等待样式调用适用于 nano.db.insert 但不适用于 nano.db.list
【发布时间】:2019-05-23 18:32:02
【问题描述】:

我在我的 nodeJS 项目中使用 https://github.com/apache/couchdb-nano 与我的 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 方式工作?

【问题讨论】:

    标签: node.js couchdb couchdb-nano


    【解决方案1】:

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

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

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

    【讨论】:

    • 非常感谢格林!我在包 json 中现有的 nano 配置是 "nano": "^6.1.2" 并且通过运行 npm i nano 它只会更新其次要版本。阅读您的建议后,我删除了以前的配置并运行了安装命令,它更新为“nano”:“^8.0.1”。并且异步等待调用按预期工作!!!
    【解决方案2】:

    您不能以这种方式使用 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

    【讨论】:

    • 感谢 Hassan 的回复,但我在函数声明中使用了 async,如下所示:(async () => { try { const databases = await nano.db.list(); console.log (数据库); } catch(err) { console.log(err); } })();
    猜你喜欢
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 2020-03-31
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多