V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
wly19960911
V2EX  ›  JavaScript

冒昧提问关于 ES6 的 promise 的一些问题

  •  
  •   wly19960911 · 2017-01-21 19:16:44 +08:00 · 3335 次点击
    这是一个创建于 2868 天前的主题,其中的信息可能已经有所发展或是发生改变。
    目前在看 promise 章节, promise 的基本概念和基本操作我都理解了,但是我不理解为什么叫 promise 是 js 的异步编程,关于 Generator 可以看作一个断点式的执行函数,但是和我在 java 或者 C 上的多线程还是有点不一样就是,这个另外说了。

    promise 可以实现异步操作结束后,将异步操作的结果传递出去。我在这些概念和使用 then , catch 之类的操作上感觉, promise 是一个线性的单线程操作,并没有什么多线程的操作,可能有人说阮一峰的教程里面有一些关于 promise 的 demo ,我也用 nodejs 实现了关于读取文件这个操作的异步,但是我不理解的是如何实现了这个异步操作的,因为使用了封装的模块。

    写到了这里我感觉我可能哪个地方理解有错误,总感觉 C 的多线程和 es6 的异步概念上有所不同,我也查了关于 js 的多线程有人说使用 settimeout 来实现,但是那种也是一种伪装的单线程操作。以及还有 web worker 这种完全的多线程操作但是好像 web worker 只能执行一个 js 文件我感觉挺麻烦的。

    那么求问 promise 该如何理解, promise 里面写着的操作并不是由 js 自动进行异步操作的,还是异步操作是自己写的?又或是 js 的异步并不能和 c 一样做到两个循环轮流执行只是断点式的执行?
    18 条回复    2017-01-22 20:39:08 +08:00
    jybox
        1
    jybox  
       2017-01-21 19:29:33 +08:00   ❤️ 2
    建议先了解 Node 的事件循环,异步能力本身是由引擎(或者 Node.js 里的 C++ Addon )提供的,引擎会在进行 IO 操作时接受一个回调函数,然后再在 IO 完成时调用它。如果不借助引擎的能力, JS 本身是做不到异步和并发的。

    Promise 只是帮助开发者更好地管理异步任务(我认为最大的价值是简化了异常处理),是可以用纯 JavaScript 来实现的, ES2015 把 Promise 加入了标准中。
    wly19960911
        2
    wly19960911  
    OP
       2017-01-21 19:39:34 +08:00 via Android
    @jybox 也就是说,纯前端并不需要深入了解 promise 的使用?如果这样的话我就简略看掉吧,感谢回答
    raighne
        3
    raighne  
       2017-01-21 19:40:48 +08:00 via iPhone
    Promise 的概念确实有点绕,自己不用框架写一个简单的 Promise 异步编程,理解了之后,还是用 async/await 吧。
    013231
        4
    013231  
       2017-01-21 19:50:36 +08:00   ❤️ 1
    “異步”和“多線程”是完全不同的概念,二者間並無必然的聯繫。

    http://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean

    “ When you execute something synchronously, you wait for it to finish before moving on to another task. When you execute something asynchronously, you can move on to another task before it finishes.”

    僅此而已。

    很多現代前端框架使用 Promise 。 ES7 的 async/await 語法也和 Promise 有關。你應該深入了解它。
    wly19960911
        5
    wly19960911  
    OP
       2017-01-21 19:51:01 +08:00 via Android
    @raighne 我的问题主要在于 promise 如何和异步协作或者本身进行异步,加上前面那个 Generator 概念一混淆头就发热了,而且没有合适的 demo 去说明
    linbiaye
        6
    linbiaye  
       2017-01-21 19:54:10 +08:00   ❤️ 1
    异步不等于多线程, js 是单线程的。你发起一个 ajax 请求后用写一个死循环,你的回调永远不会被执行。 js 的异步是借助操作系统提供的事件(通知 /轮询)来完成的。
    wly19960911
        7
    wly19960911  
    OP
       2017-01-21 19:58:34 +08:00 via Android
    @013231 看来我对于异步的概念还并不是很清楚,感谢提供思路和建议
    wly19960911
        8
    wly19960911  
    OP
       2017-01-21 20:13:41 +08:00 via Android
    @linbiaye 看来还是异步和多线程概念上踩坑了,感谢回答,因为当初做过简单的 Java 开发使用过多线程进行网络通信误以为异步=多线程
    JamesRuan
        9
    JamesRuan  
       2017-01-21 20:28:35 +08:00   ❤️ 1
    Promise 是需要深入理解的,否则到时会寸步难行。

    Promise 代表的是未来的返回值,在 Promise 创建时,动作已经开始执行;当动作结束是, then 里的方法会被调用。

    Promise 可用来做并行操作,在此安利一个我写的库,用于并发执行指定数量的 Promise ,不传参数的默认动作是串行 Promise ,即第一个 Promise 内动作结束后才开始下一个 Promise 。

    https://github.com/coffee-toolbox/parallel

    如题是 coffeescript 写的,想看 JS 版只要 coffee -c 转一下就好了。
    MinonHeart
        10
    MinonHeart  
       2017-01-21 20:31:30 +08:00
    异步和多线程没关系
    异步只是充分利用单线程(当前线程应该更准确)
    JamesRuan
        11
    JamesRuan  
       2017-01-21 20:33:49 +08:00
    当然,你学一些 FP 以后就会知道, Promise 只是一个 Monad 而已。
    ChefIsAwesome
        12
    ChefIsAwesome  
       2017-01-21 21:01:21 +08:00   ❤️ 1
    1.异步跟多线程没关系。
    2.async await 是把异步的东西弄成写起来像同步一样。
    3.promise 是个能往函数里传,也能从函数里返回的东西。当你从这个角度看 promise 的时候,它就不只是一个语法糖了。有人说 promise 是为了解决回调地狱而出现的,那是瞎扯淡。
    4.想真正利用好异步,还是得靠 rx 。
    ibudao
        13
    ibudao  
       2017-01-21 21:34:41 +08:00   ❤️ 1
    我也有过类似的困惑,读过一些 Promise 实现后清晰了很多,试着回答一下。

    当我们编写异步代码时主要跟两个东西打交道:异步 API 和回调函数。当你的程序只有一个异步调用时,你肯定可以轻松应对。但当你的程序有 N 多个异步调用,并且相互直接有着复杂的关系(多个异步调用同时发出?顺序发出?有一个失败了其它的怎么处理?)时,你的代码将充斥大量的控制变量,你感觉你已经进入了 callback hell 。更恐怖的当有人读你的代码的时候,他会感觉像吃屎一样难受。

    这个问题大部分语言都存在,只不过 JS 更受关注,人多嘛,再加上 WEB 程序天生就面对大量异步网络请求。

    所以, Promise 只是一个解决异步相关问题的“框架”,它帮你梳理异步操作模型。用它写出来的代码可读性高,容易理解,仅此而已。
    Nutlee
        15
    Nutlee  
       2017-01-22 09:57:47 +08:00
    似乎楼主是想了解 js 异步的实现原理,而不单单说 Promise/A+ 模式吧,看起来对于 ES6 的 Promise 语法楼主已经很了解了。这方面我一直也有困惑,在浏览器端(比如 AJAX ),异步的底层实现似乎是依赖浏览器的多线程机制的,那在 Node 端呢? 看到的解释都是 EventLoop , EventLoop 只能解释 setTimeout 啊(在一个线程上,延迟加入队列),对于文件读取这种异步怎么解释?? 智商捉急 同样求解答....
    ibudao
        16
    ibudao  
       2017-01-22 11:17:15 +08:00   ❤️ 1
    @Nutlee 当你调用 readFile 函数,实际上最终完成功能的是系统调用 read/fcntl 之类的函数。这类函数可以让你的 readFile 立刻返回,并且当读完数据后可以通过某种机制通知 JS 来回调你的 callback 。这个异步是 IO 的异步,想更深入了解 IO 异步原理,可以看看 APUE 的第三章和第十四章。
    Nutlee
        17
    Nutlee  
       2017-01-22 11:35:53 +08:00
    @ibudao 谢谢 明白点了 ,至少明白了都是通过某种通知机制来调度的,我去看看 谢谢。
    bombless
        18
    bombless  
       2017-01-22 20:39:08 +08:00 via Android
    其实也可以多线程啦。不过跟 promise 没啥关系,毕竟它只是用来处理能串起来的操作。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1039 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:09 · PVG 05:09 · LAX 13:09 · JFK 16:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.