在不传递变量的情况下解决承诺

Resolving promises without passing through variables

我正在学习如何使用 promises 并尝试使用函数式编程来实现代码模块化。我的问题是,当我通过 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)

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

但是在这种情况下,我只想解决 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 但我不认为我正在尝试做同样的事情。

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

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) })

这样看起来干净吗?

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);

在查看 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. 变量不需要通过'chained promises' 这意味着这些已解决的承诺的结果可以是单一的 变量而不是包含所需变量的数组和 传递的变量
  2. 进而允许'chained'promise函数接受参数 单个变量而不是使用数组的解构递增 代码的可重用性
  3. Promise.all() 在其他代码区域的使用现在更多地暗示了它 执行一系列不相关承诺的原始功能 异步
  4. 代码缩进仍然很低,可读性大大提高