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

2017-01-21 19:16:44 +08:00
 wly19960911
目前在看 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 一样做到两个循环轮流执行只是断点式的执行?
3144 次点击
所在节点    JavaScript
18 条回复
jybox
2017-01-21 19:29:33 +08:00
建议先了解 Node 的事件循环,异步能力本身是由引擎(或者 Node.js 里的 C++ Addon )提供的,引擎会在进行 IO 操作时接受一个回调函数,然后再在 IO 完成时调用它。如果不借助引擎的能力, JS 本身是做不到异步和并发的。

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

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

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

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

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

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

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

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

所以, Promise 只是一个解决异步相关问题的“框架”,它帮你梳理异步操作模型。用它写出来的代码可读性高,容易理解,仅此而已。
leer561
2017-01-22 09:13:46 +08:00
Nutlee
2017-01-22 09:57:47 +08:00
似乎楼主是想了解 js 异步的实现原理,而不单单说 Promise/A+ 模式吧,看起来对于 ES6 的 Promise 语法楼主已经很了解了。这方面我一直也有困惑,在浏览器端(比如 AJAX ),异步的底层实现似乎是依赖浏览器的多线程机制的,那在 Node 端呢? 看到的解释都是 EventLoop , EventLoop 只能解释 setTimeout 啊(在一个线程上,延迟加入队列),对于文件读取这种异步怎么解释?? 智商捉急 同样求解答....
ibudao
2017-01-22 11:17:15 +08:00
@Nutlee 当你调用 readFile 函数,实际上最终完成功能的是系统调用 read/fcntl 之类的函数。这类函数可以让你的 readFile 立刻返回,并且当读完数据后可以通过某种机制通知 JS 来回调你的 callback 。这个异步是 IO 的异步,想更深入了解 IO 异步原理,可以看看 APUE 的第三章和第十四章。
Nutlee
2017-01-22 11:35:53 +08:00
@ibudao 谢谢 明白点了 ,至少明白了都是通过某种通知机制来调度的,我去看看 谢谢。
bombless
2017-01-22 20:39:08 +08:00
其实也可以多线程啦。不过跟 promise 没啥关系,毕竟它只是用来处理能串起来的操作。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/336101

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX