【问题标题】:Resolve a function that uses Promise解析一个使用 Promise 的函数
【发布时间】:2019-08-18 08:24:58
【问题描述】:

我有以下异步函数

export default async function getUserNames(id: string[]): Promise<string[]> {
    let userNames: string[] = [];
    // We do some stuff here like calling a service, etc...

    return userNames;
}

在另一个打字稿文件上,我正在导入 getuserNames 函数并尝试像这样调用它:

const promiseResult = getUserNames(idList)
        .then(result => {
            return result;
        })
        .catch(error => {
            return undefined;
        });

    if (promiseResult) {
        // Do something else here.
    }

但是,promiseResult 类型是 Promise 而不是我所期望的 string[]。如何调用 getuserNames 函数,完成后,将实际的 string[] 返回给 promiseResult 变量?

编辑 做这样的事情是否被接受?

let varB: string[];
const promiseResult = getUserNames(idList)
        .then(result => {
            varB = result;
        })
        .catch(error => {
            varB = undefined;
        });

if (varB) {
        // Do something else here.
    }

最后,请注意调用 getUserNames 的函数未定义为异步,我无法更改。

【问题讨论】:

标签: javascript node.js typescript promise


【解决方案1】:

您无需在代码中使用 async/await。

/**
 * async data fetcher
 * @param {String} url 
 * @param {Object} options 
 * @returns {Promise}
 */
const fetch = (url, options) => {
  return new Promise((resolve, reject) => {
    fetch(url, options)
      .then((response) => {
        if (response.ok) {
          return resolve(response.json)
        }
        return reject(response.json)
      })
      .catch((error) => reject({ error }))
  })
}

/**
 * async fetch wrapper, returns a Promise
 * @param {NUmber} id 
 * @returns {Promise}
 */
const getUserNames = (id) => {
  return fetch('www.yourapi.com/get_user_names', { params: { id } })
}

const idList = [1, 2, 3]
// so, your code also will be asyncronious too:
Promise.all([getUserNames(idList)]).then((promiseResult) => {
  if (promiseResult) {
    // Do something else here.
  }
})

【讨论】:

    【解决方案2】:

    getUserNames 确实返回了 promise&lt;string[]&gt;,这正是它的签名所说的。

    您应该在then 中执行您的if (result)

    或者您可以使用新的 await 关键字,这将确保承诺在分配给 promiseResult 之前得到解决 在这种情况下,请将您的 await 包装在 try/catch 中。

    【讨论】:

    • 我明白你的意思。然后不可能在 if (result) 块之外做任何其他事情。所有依赖的代码都需要放在那里,对吧?
    【解决方案3】:

    如果您想访问 promise 解析为的值,您唯一的选择是

    1) 使用 promise 的 .then 回调

    getUserNames(idList)
      .then(result => {
        // Do something else here.
      })
    

    2) 将代码放入异步函数中并使用 await 关键字:

    async function someFunction () {
      const result = await getUserNames(idList);
      // Do something else here.
    }
    

    请注意,由于所有异步函数都返回 Promise,因此在此示例中 someFunction 将返回 Promise。

    【讨论】:

    • 只想补充一点,async 函数也会返回一个承诺
    • 我认为第二个选项对我来说不可行,因为在我调用 getUserNames 的函数中不是异步函数,我无法更改它。在第一个选项中,为什么当我在 .then(result ...) 中执行 return result 时,我可以将结果分配给 getUserNames 结果之外的变量?类似于我在主帖版本中所做的事情。
    • 澄清一下:如果我尝试在我尝试调用 getuserNames 的函数中执行 awai getUserNames,我会收到一条错误消息,提示“await”表达式只允许在异步函数中使用。
    • why when I do return result inside the .then(result ...) can I assign the result to a variable that is out of the getUserNames result? 分配给这样的变量是合法的javascript,但几乎可以肯定不是您想要做的。承诺将在未来某个未知时间解决。任何与结果同步交互的代码都会失败,因为该值还不存在。如果您想等待该值可用,那么您唯一的选择是 .then 回调或等待。是的,await 只能在异步函数中使用。
    • 谢谢,鉴于您在此处列举了两个可能的选项,我会将您的回复视为有效的回复。
    猜你喜欢
    • 2016-10-07
    • 2015-08-15
    • 2017-08-01
    • 2016-04-14
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多