【问题标题】:how is async programming (promises) implemented in javascript? isn't javascript a ui-threaded environment?javascript 中如何实现异步编程(承诺)? javascript 不是 ui 线程环境吗?
【发布时间】:2012-04-03 05:21:13
【问题描述】:

JS 中的 Promises 允许你进行异步编程,如下:

DoSomething().then(success, failure);

DoSomethingElse();

每当我编写前面的代码时,它都会在到达 success 之前到达 DoSomethingElse()。 这怎么可能? JS 不是单线程环境(不包括 web-workers)吗?用setTimeout 完成了吗?

【问题讨论】:

标签: javascript asynchronous promise


【解决方案1】:

JavaScript 中的 Promise 通常涉及某种调用链或流式方法调用 API,其中函数结果通常提供延续方法,例如 with、then、when、whenAll 等,以及一些指示结果是否确实可用的状态标志。具有输入参数的函数还可以支持承诺值,检测输入是一个承诺,并将其功能封装到一个 thunk 中,当承诺值准备好时,可以将其链接起来。

通过这些,您可以提供一个环境,其中 Promise 模拟这样的并行语言:

MyApi.LongRunningTask().then( function(result) { MyAppi.LongOtherTask(result); }).then

或长时间运行的调用不依赖的顺序用例:

var value1 = MyApi.LongRunningTask();
var value2 = MyApi.LongRunningOtherTask();

MyApi.DoSomeFunction(value1, value2).then ==> DoSomeFunction 可以检查值是否准备好,如果没有,则链接它们的 then/when 函数以执行其逻辑。

【讨论】:

    【解决方案2】:

    是的,JavaScript 是单线程的,这意味着您永远不应该阻塞这个单线程。任何长时间运行的等待操作(通常是 AJAX 调用或休眠/暂停)都使用回调实现。

    不看这里的实现会发生什么:

    1. DoSomething 被调用,它接收successfailure 函数作为参数。

    2. 它会做它需要做的事情(可能会启动长时间运行的 AJAX 调用)并返回

    3. DoSomethingElse() 被调用

    4. ...

    5. 稍后 AJAX 响应到达。它调用之前定义的successfailure 函数

    另见(类似问题)

    【讨论】:

    • 在进行 ajax 调用时,xhr 对象是打开新线程的对象,所以这不是真正的问题。如果不是 ajax 调用怎么办?例如,如果长任务是对数组进行排序怎么办?这是如何实现的?
    • @EladKatz:不是这样,当执行长时间运行的 CPU 密集型任务(如排序数组或巨大的 DOM 操作)时,UI 线程被占用并且 GUI 被阻塞(冻结)。不执行超时,不处理 AJAX 响应,不调用点击事件处理程序。对不起。
    猜你喜欢
    • 2020-09-20
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2023-03-17
    • 2017-10-17
    相关资源
    最近更新 更多