我想知道在处理 JavaScript 中的异步代码时,这两种方法中哪一种更好。我想了解哪种方法会导致代码更清晰。我习惯使用 Promise,它们似乎比异步方法更灵活(https://github.com/caolan/async)。
我也知道 Task.js 库 ( http://taskjs.org/ ),但这依赖于 Ecmascript Harmony 中的 yield 关键字。
我想知道在处理 JavaScript 中的异步代码时,这两种方法中哪一种更好。我想了解哪种方法会导致代码更清晰。我习惯使用 Promise,它们似乎比异步方法更灵活(https://github.com/caolan/async)。
我也知道 Task.js 库 ( http://taskjs.org/ ),但这依赖于 Ecmascript Harmony 中的 yield 关键字。
该async
库封装了一些非常常见的异步模式,包括并行进行任意异步调用和异步迭代列表。它旨在与“nodeback” (err, res)
API 一起工作,这使得它对许多 Node.js 应用程序都很有用。async
然而,它是一个特定的解决方案,它只简化了库中包含的异步模式。
相比之下,Promise 在我看来是解决异步代码问题的更通用的解决方案。乍一看,它们不仅提供了错误冒泡和扁平化回调金字塔的明显好处,而且async
可以更简单地解决原本需要封装各种复杂模式的问题。
我将通过一些async
可用的模式快速浏览来演示这一点。例如,该async.waterfall
函数的使用如下:
async.waterfall([
function (cb) {
asyncCall('argument', cb);
},
function(resultOfFirstCall, cb) {
anotherCall(resultOfFirstCall, 'someOtherArgument' cb);
},
], function(err, res) {
if (err) handle(err);
useFinalResult(res);
});
在大多数 Promise 库中没有等价物async.waterfall
(或者至少在 Q 中没有),因为使用 . 从头开始实现它非常简单Array.reduce
,就像这样(基于 Q 的示例,但在其他 Promise 库上几乎相同):
[
function() {
return asyncCall('argument');
},
function(resultOfFirstCall) {
return anotherCall(resultOfFirstCall, 'someOtherArgument');
}
].reduce(Q.when, Q())
.then(useFinalResult, handle);
async
include中的其他大函数async.parallel
,其中 Q 包括Q.all
:
// async
async.parallel([
asyncFunc,
asyncFunc2
], function(err, res) {
if (err) handle(err);
useFinalResult(res);
// res[0] === asyncFuncResult
// res[1] === asyncFunc2Result
});
// Q
Q.all([
asyncFunc(),
asyncFunc2()
]).then(useFinalResult, handle);
和async.map
。当您使用 Promise 时,您实际上并不需要 ,因为正常就足够了:async.map
Array.map
// async
async.map(['file', 'file2', 'file3'], fs.stat, function(err, res) {
if (err) handle(err);
useFinalResult(res);
});
// Q
Q.all(['file', 'file2', 'file3']
.map(Q.nfbind(fs.stat)))
.then(useFinalResult, handle);
其余部分async
同样容易简洁地实现,使用你的 promise 库中相对简单的部分。(请注意,最后一个示例使用了一个函数Q.nfbind
:nfbind
并且 Q 提供的其他nf*
函数基本上是您将 Promise 与 nodeback API 一起使用所需的全部内容,因此尝试将 Promise 与期望 nodebacks 的库一起使用甚至没有特别大的障碍。)
最后,是否使用 Promise 或 nodebacks 取决于您,但我认为 Promise 是一种更灵活、更有能力且通常更简洁的方式来实现大多数异步操作。
回调是必要的,promise 是功能性的,值得一读,以了解更多关于这方面的信息。
由于您使用节点标记了您的问题,因此我推荐使用异步库。控制流函数非常适合使用并消除了丑陋且难以遵循的回调链。该 API 的设置非常适合将遵循节点签名的回调注入(error, result)
到控制函数中。它基本上默认包含在我编写的几乎所有节点脚本中。
虽然您也可以将 async 用于客户端,但对于大多数项目来说可能没有必要。jQuery 包含 Promise,你可以用它们完成同样的事情。
我认为 promise/a 和 async lib 具有不同的目标,promise 专注于一步异步操作进度,而 async 专注于多步骤异步操作,对于 node,async 对很多异步 api 有更广泛的用途。
顺便说一句,要处理异步操作,使用命名函数而不是匿名函数将是最有效的方法
gumballhead 推荐async.js,但如果您使用 Node.js,我建议您使用Parse Cloud Code。他们的 API 内置了 Promise,以及其他好东西(如数据库)。它节省了时间,您不必担心后端的稳定性。您可以包含任何 NPM 模块,module.exports
只需对exports
. 它还与您的前端无缝集成!我在当前项目中使用这种方法取得了成功,只是想用一种新方法发表评论。
随意评论您为什么/何时不应使用Cloud Code;因为我还没有这样的经历。