- 1、解释如何使用Thunk解决回调地狱
- Thunk 就是利用柯里化将异步函数的回调函数参数分离出来,生成只接受一个参数(回调函数)的函数,这样保证异步任务的统一性,就可以利用数组的reduce操作统一处理,避免嵌套过多出现回调地狱
- Thunk函数在Javascript中,目的就是将多参数函数(入参中包含了callback函数)变成单参数版本的函数。而且单参数只能是callback函数。Thunk函数实现上是针对多参数的currying(柯里化),来实现对函数的惰性求值任何函数, 只要参数有回调函数, 就能写成Thunk函数的形式。
- 2、解释一下如何用Promise解决回调地狱
- 1、
- promise对象可以用来包括异步代码,一个promise实例一旦new出来了之后,它只会有三种状态,初始为pending,成功为fulfilled,失败为rejected。
- 状态的改变有内部提供的resolve和reject方法来触发,再通过then方法去拿到resolve和reject出来的值。
- 由于promise是链式调用的,你在then方法里面还是继续return 值出来,return出来的又是一个promise,又可以继续使用then去获取刚才return出来的值,就是利用这样的链式调用的特性,可以让我们解决回调地狱。
- 2、
- 通过:回调函数延迟绑定、返回值穿透、错误冒泡来解决的
- 回调函数延迟绑定:回调函数不是直接声明的,而是通过后面的 then 方法传入的,即延迟传入
- 返回值穿透:我们根据 then 中回调函数的传入值创建不同类型的 Promise,然后把返回的 Promise 穿透到外层,以供后续的调用。
- 错误冒泡:在then的调用中,前面产生的错误会一直向后传递,被 catch 接收到,就不用频繁地检查错误了。
- 1、
- 3、解释一下Promise与观察者模式的关系
- 又称作为发布-订阅模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者对象之间通讯和耦合的问题\
- Promise也使用了观察者模式的原理
- then方法注册了成功事件
- catch方法注册失败事件
- resolve(value) 发布成功事件传参
- reject(err)发布失败事件传参
- 4、解释一下Generator是如何解决回调地狱的
- generator允许用 function 声明一个生成器,生成器执行后返回一个迭代器(f), 生成器内可以使用 yield 关键字。
- 每次执行 f.next() 时,函数一直执行到 yield 关键字,暂停整个函数的执行,并且返回 yield 语句的值。
- 每次执行 f.next()都会执行到yield 关键字,直到下次碰到 yield 或者执行完毕。
- 可以把回调数据放在yield关键字 后面,在next时候可以获取到yield的值
- 5、Co函数的作用,如何编写Co函数?
- co函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行。
- 使用 co 的前提条件是:Generator 函数的 yield 命令后面,只能是 Thunk 函数或 Promise 对象。
- Generator 函数就是一个异步操作的容器。它的自动执行需要一种机制,当异步操作有了结果,能够自动交回执行权。
- 两种方法可以做到这一点:
- 回调函数。将异步操作包装成 Thunk 函数,在回调函数里面交回执行权。
- Promise 对象。将异步操作包装成 Promise 对象,用 then 方法交回执行权。
function run(gen){
var g = gen();
function next(data){
var result = g.next(data);
if (result.done) return result.value;
result.value.then(function(data){
next(data);
});
}
next();
}
run(gen); // gen 是一个 Generator 函数
只要 Generator 函数还没执行到最后一步,next 函数就递归调用,从而实现自动执行。
- 6、解释一下Async/Await的原理
- async 函数是什么?一句话,它就是 Generator 函数的语法糖。
- async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
- (1)内置执行器。
- Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。这完全不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。
- (2)更好的语义。
- async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
- (3)更广的适用性。
- co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。
- (4)返回值是 Promise。
- async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
- 进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。