如何在没有线程的情况下在Javascript中实现Promise

最近,我已经看到Promise的概念在AngularJS和JQuery中实现。

我已经在下面的代码中看到了Java中的Futures的实现,但是这需要在语言/平台中存在线程池的概念。 但是,Javascript中没有这样的线程概念。 如何实现Javascript中的Promise?

public class Futures1 { private static final ExecutorService pool = Executors .newFixedThreadPool(10); public static void main(String[] args) { Future contentsFuture = null; try { contentsFuture = startDownloading(new URL("http://www.example.com")); } catch (MalformedURLException e) { e.printStackTrace(); } // other computation try { final String contents = contentsFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } public static Future startDownloading(final URL url) { return pool.submit(new Callable() { @Override public String call() throws Exception { try (InputStream input = url.openStream()) { return IOUtils.toString(input, StandardCharsets.UTF_8); } } }); } } 

发明Promise是为了帮助管理异步操作,并且承诺自己不需要线程来实现这一点。 它们本质上是为异步操作提供簿记的对象 – 保持状态转换的状态标志,结果值和监听器。 这些都可以通过常规的单线程Javascript轻松完成。

因此,只要您具有异步操作(但是这些操作已实现),您就可以从promises中受益,并且不需要线程来实现它们。

您在Java代码中看到的代码是帮助在单独的线程中运行常规任务的代码(为同步操作提供一些异步类型的行为)。 这不是承诺所做的。 因此,如果您已经在您的环境中进行了异步操作,那么您就不需要这种类型的代码来使用promises。

Javascript中异步事物的示例几乎是您注册的任何内容,实际事件在将来的某个时间发生,其他代码可以在该事件触发之前运行。 在浏览器的Javascript环境中,这包括setTimeout() ,键盘事件,鼠标事件,ajax完成回调等等……这些都是异步事件。 您注册了对它们的兴趣(通过注册事件监听器或将回调传递给某个函数)。 在Javascript实现的内部,可能存在使这些异步事件工作的线程,但是这些线程不需要直接向程序员公开,以实现异步function。 例如,请参阅此post ,了解Javascript如何在其他Javascript事件运行时在后台运行ajax调用。 您需要知道的是,您的回调函数将在未来被称为某个不确定的时间。

因此,在Javascript中,promises用于管理环境中已存在的异步操作。 它们不用于使非异步事物变得异步(为了做到这一点,你需要线程)。

请记住,promises本身只是监视工具,用于监视现有的异步操作。 除了setImmediate()nextTick()本身并不是异步的.then()它可以使用内置API实现,例如setTimeout()setImmediate()nextTick() 。 Promise不需要自己的本机代码或线程。 实际上,如果需要,您可以在普通的单线程Javascript中编写promise实现。

JavaScript层下面的浏览器编写的本机代码往往非常巧妙地实现了线程。 事实certificate,这通常是你所需要的。 在JavaScript中执行实际的计算工作往往不需要Promise(虽然工作人员更容易),但是用于加载外部资源,并在完成后获得回调。 JS Promises只是将回调分配给像“image.onLoad”这样的函数,并检查是否通知另一个函数。

Hogan可能最好地总结了它 – 基于事件的编程。