保持承诺链可读 [英] Keeping Promise Chains Readable

查看:52
本文介绍了保持承诺链可读的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经习惯了承诺链接数组。当每个承诺是一个很长的行时,非常容易阅读承诺链,例如

I've grown used to promise chaining arrays. It's incredibly easy to read a promise chain when each promise is a line long such as

myArray.map(x => convertX)
  .filter()
  .whatever()
  .etc()

这非常容易阅读。但是,当我使用自定义函数创建promise链时,它会变得更加混乱。

This is incredibly easy to read. However, when I create promise chains with custom functions, it gets much messier.

database.query(first query)
  .then(results => {
    // do stuff
    // do more
    // even more
    return database.query(second query)
  })
  .then(results => {
    // rinse and repeat
  })
  .catch(err => { 
    // error handling 
  })

现在,这可以清晰,但当承诺链进一步扩展时,它会得到多一点。如果我让每个承诺都是它自己的功能,那么我可以简化流程,所以代码看起来像这样(imo,1000x更易读)。

Now, this can be legible, but when the promise chain extends further, it gets to be a little much. If I make each promise it's own function, then I can streamline the process so the code looks something like this (which imo, is 1000x more legible).

db.query(first query)
  .then(storeFirstQuery)
  .then(secondQueryAndStoreIt)
  .then(thirdQueryAndStoreIt)
  .catch(errHandlingFunction)

这样,我可以重新排列函数,而无需操纵从一个promise传递到的值。下一个。如果一个承诺使用了另一个的结果,它只需要在另一个之后,而不是紧接在另一个之后。这样我就可以在任何需要的地方潜行承诺。

This way, I can rearrange the functions without having to manipulate the values that get passed from one promise to the next. If a promise uses a result of another, it only needs to be after the other, but not immediately after. That way I can sneak promises in wherever I need.

但是,这需要我的承诺链使用每个承诺范围之外的变量。有没有一种经过验证的方法呢?

However, this requires my promise chain to use variables outside each promise's scope. Is there a tried and true way to do this?

编辑 - 似乎 async / await 是最好的方法,但是我在Heroku上运行Node并且它还不支持:/

Edit - Seems async/await is the best way to do this, but I'm running Node on Heroku and it's not supported yet :/

推荐答案

嗯,你可以使用承诺这样的东西:

Well, you can use something like that with promises:

myArray.map(x => convertX)
  .filter()
  .whatever()
  .etc()

如果你从npm使用我的 rsp 模块。

if you use my rsp module from npm.

除此之外,您可以使用 async / 等待 ES2017的功能来简化承诺链,特别是它们的范围。

Other than that you can use the async/await features of ES2017 to simplify the promises chains, especially their scope.

因为代码是这样的:

db.query(first query)
  .then(storeFirstQuery)
  .then(secondQueryAndStoreIt)
  .then(thirdQueryAndStoreIt)
  .catch(errHandlingFunction)

如果需要的话要在最后一个 thirdQueryAndStoreIt()处理程序中使用第一个查询的结果,您在访问超出范围的数据时遇到问题。但是当你这样做时:

if you need to use the result of first query in the last thirdQueryAndStoreIt() handler, you have a problem with accessing the data that is out of scope. But when you do:

try {
    let a = await db.query(first query);
    let b = await storeFirstQuery();
    let c = await secondQueryAndStoreIt();
    let d = await thirdQueryAndStoreIt(a); // use 'a' here
} catch (e) {
    errHandlingFunction(e);
}

那么你没有范围问题,因为你可以轻松访问以前分配的所有变量。

then you don't have the problem with scope, as you can easily access all of the previously assigned variables.

有关支持此语法的节点版本,请参阅此内容:

See this for Node versions that support this syntax:

  • http://node.green/#ES2017-features-async-functions

您可以将它与Node v7.6 +开箱即用,或与Node v7.0 +一起使用 - harmony flag。

You can use it with Node v7.6+ out of the box or with Node v7.0+ with the --harmony flag.

对于较旧的Node版本,您可以使用 co <​​/a>或 Bluebird.coroutine 使用生成器函数和 yield 而不是 await

For older Node versions you can use co or Bluebird.coroutine for a similar syntax using generator functions and yield instead of await.

这篇关于保持承诺链可读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆