1

我对 Javascript 中的 Promises 比较陌生,但最近爱上了它们的优雅,尤其是在 Bluebird 库中。

这可能是一个新手问题,但是如何将正常同步的函数转换为异步运行?例如,如果我想Math.random()*RANGE并行计算 30 次,我该如何使用 Promise(在 Q 或 Bluebird 中)来做到这一点?

4

2 回答 2

2

你不能。Promise 不会“使代码并行”,它们只是为异步代码提供了更好的抽象——它们没有比回调更强大的功能

同步代码将始终同步执行,并且 - 由于 JavaScript 的单线程特性 - 不可并行化。即使你给它一个回调,它的执行是通过使用一个实际的异步函数来推迟的,这只会将回调推迟到后面的事件循环切片,但不会让你的同步任务与其他任何东西并行执行——而且不会让它执行得更快。它只会有助于将长时间运行的代码分解成块(请参阅此处此处),这可以使应用程序感觉更快。

您可以做的是在另一个线程(WebWorker节点集群等)上执行代码并使用事件将结果传回。对于这些事件,您可以编写一个不错的 promise 抽象;但说真的 - 线程的开销对于生成 30 个随机数来说太大了。

于 2014-07-19T07:59:27.870 回答
2

首先,promise 不会帮助你让代码并行运行。它们是在您的任务完成时运行其他代码或将此任务与其他任务协调的工具。但是让你当前的代码与其他代码并行运行与 Promise 无关。

其次,采用同步任务并试图使其更像异步任务的工作几乎没有优势(并且有很多复杂性),除非它运行时间过长以至于干扰其他操作的响应性。计算一组随机数不太可能是一项耗时的任务。

如果你真的想在浏览器中并行执行,你会去使用 WebWorkers,这是在基于浏览器的 javascript 中创建真正独立的执行线程的唯一方法。除了 WebWorkers,浏览器中的 javascript 是单线程的,因此没有并行执行。可以在连续调用上执行小块代码,setTimeout()这会将您的代码执行与浏览器中发生的其他事情交织在一起,并且可以允许其他浏览器任务在运行另一个长时间运行的任务时保持响应。

setTimeout()您可以在此处查看以块形式处理大型数组的示例迭代数组而不阻塞 UI以允许其他事物在处理块之间运行的最佳方式。Promise 可以添加到这样的东西中,作为管理任务完成或管理其与其他任务的协调的一种方法,但 Promise 实际上并不能帮助您使其分块工作。

于 2014-07-19T16:54:40.690 回答