最近,我一直看到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<String> 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<String> startDownloading(final URL url) {
return pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
try (InputStream input = url.openStream()) {
return IOUtils.toString(input, StandardCharsets.UTF_8);
}
}
});
}
}
答案 0 :(得分:31)
发明Promise是为了帮助管理异步操作,并且承诺自己不需要线程来实现这一点。它们本质上是为异步操作提供簿记的对象 - 保持状态转换的状态标志,结果值和监听器。这些都可以通过常规的单线程Javascript轻松完成。
因此,只要你有异步操作(但是这些操作已经实现),你就可以从承诺中受益,并且不需要线程来实现它们。
您在Java代码中看到的代码是帮助在单独的线程中运行常规任务的代码(为同步操作提供一些异步类型的行为)。这不是承诺所做的。因此,如果您已经在您的环境中进行了异步操作,那么您就不需要这种类型的代码来使用promises。
Javascript中异步事物的示例几乎是您注册的任何内容,实际事件将在未来的某个时间发生,其他代码可以在该事件触发之前运行。在浏览器的Javascript环境中,这包括setTimeout()
,键盘事件,鼠标事件,ajax完成回调等等......这些都是异步事件。您注册了对它们的兴趣(通过注册事件监听器或将回调传递给某个函数)。在Javascript实现的内部,可能存在使这些异步事件工作的线程,但是这些线程不需要直接向程序员公开,以实现异步功能。例如,请参阅this post,了解Javascript如何在其他Javascript运行时在后台运行ajax调用。您需要知道的是,您的回调函数将在未来被称为某个不确定的时间。
因此,在Javascript中,promises用于管理环境中已存在的异步操作。它们不用于使非异步事物变得异步(为了做到这一点,你需要线程)。
请记住,promises本身只是监视工具,用于监视现有的异步操作。除.then()
之外,Promise实际上并不是异步的,setTimeout()
可以使用内置API实现,例如setImmediate()
或nextTick()
或{{1}}。 Promise不需要自己的本机代码或线程。实际上,如果需要,可以在普通的单线程Javascript中编写promise实现。
答案 1 :(得分:2)
JavaScript层下面的浏览器编写的本机代码往往非常巧妙地实现了线程。事实证明,这通常是你所需要的。在JavaScript中执行实际的计算工作往往不需要Promise(虽然工作人员更容易),但是用于加载外部资源,并在完成后获得回调。 JS Promises只是将回调分配给像“image.onLoad”这样的函数,并检查是否通知另一个函数。
Hogan可能最好地总结了它 - 基于事件的编程。
答案 2 :(得分:0)
我认为Roamer-1888对OP的评论可能是将其他答案中的信息提炼成易于理解的关键。
以这种方式思考-Promise不提供异步性,但在处理其他方式提供的异步性方面在语法上很方便。 -漫游者1888
JS是单线程的,但是JS运行的环境可以利用其他线程。以浏览器为例:JS可以访问Web API(例如fetch
),这些API允许它通过浏览器引擎在单线程JS环境之外(无论是网络环境)执行工作。请求,由网络工作者处理的事情,无论如何。承诺只是跟踪这些操作并在完成后接收其结果。