【问题标题】:Resolving promises without passing through variables在不传递变量的情况下解决承诺
【发布时间】:2018-04-10 02:17:27
【问题描述】:

我正在学习使用 Promise 并尝试使用函数式编程来实现代码模块化。我的问题是,当我通过then() 链时,我正在通过中间then() 调用传递参数以供以后使用的函数。

这感觉没有必要,我想我只见树木不见森林。

function getSession(user, pass) {
    return new Promise((resolve) => {
        // do something with user and pass
        resolve(session)
    })
}


function getAccount(session) {
    return new Promise((resolve) => {
        // do something with session - pass through session
        resolve([session, account])
    })
}

function doThing(session, account) {
    return new Promise((resolve) => {
        // do something with account - pass through session
        resolve([session, thing])
    })
}

function doOtherThing(session, thing) {
    return new Promise((resolve) => {
        // do something with session and thing
        resolve(otherThing)
    })
}

let example = getSession(user, pass).then(getAccount).then(doThing).then(doOtherThing)

例如,doThing() 被传递给 sessionaccount,但只对 account 执行某些操作。但是,由于doOtherThing() 需要session,我通过会话实例,以便该函数可以使用它。

所以为了消除通过这些额外的变量,我想做类似的事情

function getAccount(session) {
    return new Promise((resolve) => {
        // do something with session
        resolve(account)
    })
}

function doThing(account) {
    return new Promise((resolve) => {
        // do something with account
        resolve(thing)
    })
}

let session = getSession(user, pass)
let thing = getSession(user, pass).then(getAccount).then(doThing)
let example = doOtherThing(session, thing)

如您所见,这些函数中的大多数都返回一个承诺,因此我可以通过在其他地方链接来提高代码模块化。因此,sessionthing 变量被分配了 Promise。

但是在这种情况下,我只想解决 sessionthing 中的两个承诺,然后在 doOtherThing(session, thing) 中使用

我尝试了类似的东西

let session = getSession(user, pass).resolve()
let thing = getSession(user, pass).then(getAccount).then(doThing).resolve()

let example = doOtherThing(session.resolve(), thing.resolve())

但我收到 resolve is not a function 错误。

我也知道

let session = getSession(user, pass)
let thing = getSession(user, pass).then(getAccount).doThing(account)
let example = doOtherThing(session, thing)

没有意义,因为两个变量中的承诺需要在将它们传递给doOtherThing() 之前解决,但我对如何做到这一点持空白 - 所以这是更多的伪代码,表明我没有想通过会话

我查看了this question,但我不认为我正在尝试做同样的事情。

【问题讨论】:

  • 您可能对此感兴趣:How to chain promise and share prior results.
  • 这可能会有所帮助:stackoverflow.com/questions/28250680/…
  • 如果您 example 是一个接受 [user,pass] 并返回 otherThing 的函数,那么您可以对转换 [user,pass] => session => thing => [session,thing] => otherThing 的函数进行硬编码并使用闭包,但如果函数本身被传递或定义为函数数组?您可以映射它们并使用称为线程的实用程序,可以找到一个示例here

标签: javascript asynchronous promise chaining


【解决方案1】:

好的,所以我想出了一个方法 - 不确定它是否是最干净的,但它消除了通过变量的传递

let session = getSession(user, pass)
let thing = session.then(getAccount).doThing(account)

Promise.all([session, thing])
    .then((promises => { 
        [session, thing] = promises

        return doOtherThing(session, thing) 
    }))
    .then(otherThing => { console.log(otherThing) })

【讨论】:

  • 这一行在严格模式下可能会给你错误,因为未声明的 var [session, thing] = promises
【解决方案2】:

这样看起来干净吗?

let session = getSession(user, pass)
let thing = session.then(getAccount).doThing(account)

Promise.all([
  session,
  thing
]).then(data => {
  return doOtherThing(...data)
}).then(anyOtherThing => {
  console.log(anyOtherThing)
}).catch(console.log);

【讨论】:

    【解决方案3】:

    查看another answer 之后,似乎最干净、最易读的方法是使用async

    function getAccount(session) {
        return new Promise((resolve) => {
            // do something with session
            resolve(account)
        })
    }
    
    function doThing(account) {
        return new Promise((resolve) => {
            // do something with account
            resolve(thing)
        })
    }
    
    const main = async () => {
        let session = await getSession(user, pass)
        let account = await getAccount(session)
        let thing = await doThing(account)
        let otherThing = await doOtherThing(session, account)
    
        return(otherthing)
    }
    
    let otherThingResult = main()
    

    这允许以熟悉的同步代码样式执行 Promise,并带来许多优势;

    1. 变量不需要通过“链式承诺”传递 这意味着这些已解决的承诺的结果可以是单一的 变量而不是包含所需变量的数组和 传递的变量
    2. 这反过来又允许“链式”承诺函数参数接受 单个变量而不是使用增加的数组解构 代码的可重用性
    3. 在其他代码区域使用Promise.all() 现在更多地暗示了它 执行一系列不相关的承诺的原始功能 异步
    4. 代码缩进很少,可读性大大提高

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-03
      • 2020-07-05
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2014-10-24
      相关资源
      最近更新 更多