【问题标题】:How to use Promises with output from a function?如何将 Promises 与函数的输出一起使用?
【发布时间】:2021-09-07 23:20:14
【问题描述】:

在下面的脚本中,我需要为 listSpaces() 实现一个 Promise,因为它使用 axios 从外部获取数据。

Reading this我不明白

如果条件满足,Promise 将被解决,否则它 会被拒绝

在我的情况下,listSpaces() 可以返回一个空数组或一个包含元素的数组。

问题

他所说的条件是什么?那怎么能和我的listSpaces()联系起来呢?

#!/usr/bin/env node

const yargs = require('yargs');
const listSpaces = require('./functions/cmdListSpaces');

yargs.command({
  command: 'list-spaces',
  describe: 'List spaces',
  type: 'boolean',
  handler(argv) {
    const a = listSpaces();
    a.forEach((v) => {
      console.log(v);
    });
  },
}).argv;

listSpaces()

const toml = require('./toml');
const config = toml('config/kibana.toml');
const axios = require('axios');
    
module.exports = async () => {
  const r = await axios({
    method: 'get',
    url: `${config.Url}api/spaces/space`,
    auth: {
      username: config.Username,
      password: config.Password,
    },
    headers: { 'kbn-xsrf': true },
  })
    .then(response => {
      let a = [];
      response.data.forEach((v) => {
        a.push(v.id);
      });
      return a;
    })
    .catch(error => {
        return error.response.data.statusCode;
  });
};

【问题讨论】:

  • “他所说的条件是什么?” - 在他的伪代码中直接出现在该文本行之后的条件 oO 确定resolve() 是否存在的条件或者应该执行reject() 回调。
  • 我认为您不需要像这样一起使用.thenawait....您可以简单地这样做:const r = await axios.get(...); 并在下一行中,没有@987654335 @,你可以这样做r.data.foreach
  • "Reading this" - 这是一篇非常糟糕的文章。它甚至不使用the proper terminology for promises
  • "这怎么可能与我的listSpaces() 联系在一起?" - 一点也不。您没有使用 promise 构造函数,您不必检查条件来决定是要调用 resolve 还是 reject
  • "在我的情况下,listSpaces() 可以返回一个空数组或包含元素的数组" - 实际上,它没有。它还可以返回状态码。您可能希望 thrownew Error 使用状态代码和消息来代替。

标签: javascript node.js ecmascript-6 promise axios


【解决方案1】:

Reading this,我不明白

这是一篇非常糟糕的文章。它甚至不使用the proper terminology for promises

他说的是什么条件?

正如@Andreas 在评论中提到的那样,他指的是他的伪代码中直接出现在该行文本之后的条件。

那怎么会和我的listSpaces()联系在一起呢?

一点也不。您没有使用 Promise 构造函数,您不必检查条件来决定是要调用 resolve 还是 reject

在我的情况下,listSpaces() 可以返回一个空数组或一个包含元素的数组

其实不然。它还可以返回状态码。您可能希望 thrownew Error 使用状态代码和消息。

在下面的脚本中,我需要为listSpaces() 实现一个 Promise

你已经做到了。问题在于您的命令 handler 并没有预料到这个承诺,并试图在它上面调用 forEach

解决上述问题,您还 should not mix then/catch syntax with async/await。选择方法语法:

yargs.command({
  command: 'list-spaces',
  describe: 'List spaces',
  type: 'boolean',
  handler(argv) {
    listSpaces().then(a => {
//              ^^^^^^^^^^
      a.forEach((v) => {
        console.log(v);
      });
    });
  },
}).argv;

function listSpaces() { // no async here!
  return axios({
//^^^^^^
    method: 'get',
    url: `${config.Url}api/spaces/space`,
    auth: {
      username: config.Username,
      password: config.Password,
    },
    headers: { 'kbn-xsrf': true },
  }).then(response => {
    let a = [];
    response.data.forEach((v) => {
      a.push(v.id);
    });
    return a;
  }).catch(error => {
    throw new Error(error.response.data.statusCode);
  });
}

async/await:

yargs.command({
  command: 'list-spaces',
  describe: 'List spaces',
  type: 'boolean',
  async handler(argv) {
//^^^^^
    const a = await listSpaces();
//            ^^^^^
    a.forEach((v) => {
      console.log(v);
    });
  },
}).argv;

async function listSpaces() {
  try {
    const response = await axios({
//  ^^^^^^^^^^^^^^^^^^^^^^
      method: 'get',
      url: `${config.Url}api/spaces/space`,
      auth: {
        username: config.Username,
        password: config.Password,
      },
      headers: { 'kbn-xsrf': true },
    });
    let a = [];
    response.data.forEach((v) => {
      a.push(v.id);
    });
    return a;
  } catch(error) {
//  ^^^^^^^^^^^^
    throw new Error(error.response.data.statusCode);
  }
}

【讨论】:

  • 在您的第一个示例中,您 return axios 和后来的 return alistSpaces() 中。第一个return 是一个承诺(我想),第二个是函数输出。所以这个函数现在有两个返回,第一个是用“promise”“标记”的,所以它不会与函数输出混淆?
  • 第一个return返回promise链(由axios().then().catch()链式调用创建的promise)并在listSpaces()调用期间立即执行,第二个return在@987654349内部@callback 并提供 promise 将被解析的值,并在链中的前一个 promise 完成并运行回调时执行。
  • 如果return 里面有catch() 是否也会返回then
  • @SandraSchlichting 不,这将提供由.catch() 返回的承诺的解析值。 (如果回调被实际执行。如果调用.catch() 的promise 被满足,结果只是传播到返回的promise)。
猜你喜欢
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 2016-09-24
  • 2016-01-23
  • 2021-12-02
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
相关资源
最近更新 更多