Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 中异步的初步了解 #12

Closed
Tracked by #6
swiftwind0405 opened this issue Feb 25, 2020 · 3 comments
Closed
Tracked by #6

JavaScript 中异步的初步了解 #12

swiftwind0405 opened this issue Feb 25, 2020 · 3 comments

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Feb 25, 2020

JavaScript中有很多异步编程方式:

  • callback
  • promise
  • generator
  • async await
  • RxJS

callback

当一个函数传入“另外一个函数”作为参数时, 我们就可以把这个函数叫做 Callback 函数。 而这里的“另外一个函数”也有一个常见的名字: 高阶函数(Hight order function)。

Callback 并非都是异步执行的。 比如, 在我们常用的 Array.prototype.map() 中,其第一个参数也是一个回调函数,但它是同步执行的。

Callback 存在着以下2个问题而饱受诟病:

  • 控制反转:即 callback 函数的调用在一定程序上是不受我们控制的,我们缺少可靠的机制确保回调函数能按照预期被执行
  • 难以理解:即令人生畏的回调地狱

Promise

所谓Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事情(通常是一个异步操作)。从语法上说,Promise是一个对象,从他可以获取异步操作的消息。

Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

  • resolve函数的作用是,将promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
  • reject函数的作用是,将promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

promise对象生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。then方法可以接受两个回调函数作为参数。第一个回调函数是promise对象的状态变为Resolved时调用,第二个回调函数是promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受promise对象传出的值作为参数。

使用 Promise 构造函数时,必须调用 resolve()reject() 回调。

当链接 .then.catch 时,将它们视为一系列步骤会很有帮助。每个 .then 都接收前一个 .then 返回的值作为其参数。但是,如果 “step” 遇到错误,则任何后续的 .then “ steps” 都将被跳过,直到遇到 .catch。如果要覆盖错误,要做的就是返回一个非错误值。可以通过任何随后的 .then 访问。

var p = new Promise((resolve, reject) => {
    reject(Error('The Fails!'))
  })
  .catch(error => console.log(error))   // The Fails!
  .then(error => console.log(error))    // undefined

Promise 也有一些缺陷被人诟病,主要体现在以下两个方面:

  • 一旦开始执行就没办法手动终止;在满足一些条件时我们可能会希望不再执行后续的then,这在Promise中就很难优雅的做到;
  • 我们无法完全捕获可能的错误。比如说 .catch 中的错误就难以再被捕获;

async/await

async/await其实是 Promise 的语法糖,它能实现的效果都能用 then 链来实现,它是为优化 then 链而开发出来的。async 声明 function 是异步的,await等待某个操作完成。语法上强制规定 await 只能出现在 asnyc 函数中。

async 函数返回的是一个 Promise 对象。
await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,就是没有特殊限定)。

async 函数的一些缺陷如下:

  • await 关键字只能结合 Promise 控制异步;
  • 无法在外界取消一个正在运行中的 async 函数;

我们应当明确,async 函数并非一种让 generator 更便于使用的语法糖。async 函数只有在结束时,才会返回的是一个 Promise。我们无法控制其中间状态,而 generator 返回的是迭代器,迭代器让你有充分的控制权。

参考资料

@swiftwind0405 swiftwind0405 changed the title 【Day05】异步 【Day06】异步 Feb 27, 2020
@swiftwind0405
Copy link
Owner Author

https://villainhr.com/page/2016/08/25/async的generator实现

http://scriptoj.mangojuice.top/problems/72?problemsGroupId=593c151a8bf3445a88fa79be

juejin.im/post/5b04c7db6fb9a07aa542a772

juejin.im/post/5ca99e8c6fb9a05e786c9e19

segmentfault.com/a/1190000006720137

sinaad.github.io/xfe/2016/07/12/going-async-with-es6-generators

YvetteLau/Blog#28

@swiftwind0405
Copy link
Owner Author

@swiftwind0405 swiftwind0405 changed the title 【Day06】异步 【Day06】JavaScript初步了解之异步 Mar 26, 2020
@swiftwind0405 swiftwind0405 changed the title 【Day06】JavaScript初步了解之异步 【Day06】异步的初步了解 Mar 29, 2020
@swiftwind0405 swiftwind0405 changed the title 【Day06】异步的初步了解 【JavaScript】异步的初步了解 Apr 29, 2020
@swiftwind0405 swiftwind0405 changed the title 【JavaScript】异步的初步了解 JavaScript 中异步的初步了解 Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant