Promise构造函数接受一个函数作为参数吗?

  • 模拟一个Promise的最简单实现

Promise对象是一个构造函数,用来生成Promise实例,构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject,它们是两个函数,由JavaScript引擎提供,不用自己部署。
其中,resolve函数在异步操作成功时调用,并将异步操作的结果作为参数传递出去;
reject函数在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
来看一个Promise的例子:


上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果,这里的setTimeout相当于一个异步操作,过了100ms以后异步操作成功返回后调用resolve,此时done作为resolve的参数同样会传给then的第一个函数。

再来一个异步加载图片的例子比较接地气:

这里例子就很直观了,使用Promise包装了一个图片加载的异步操作,如果加载成功,就调用resolve方法,否则就调用reject方法。

下面是用Promise对象实现Ajax操作的例子:

上面代码中,getJSON是对XMLHttpRequest对象的封装,用于发出一个针对JSON数据的HTTP请求,并且返回一个Promise对象。如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数


上面代码中,总结就是以下两点:

  • Promise实例新建后会立即执行
  • then方法指定的回调函数会在当前脚本所有同步任务执行完才会执行(所以这里的resolve最后才会输出)

resolve函数的参数除了正常的值以外,还可能是另一个Promise实例:

即,一个异步操作的结果是返回另一个异步操作。
注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是resolved或者rejected,那么p2的回调函数将会立刻执行。

前面也说过,Promise新建后就会立即执行,所以直接就会进入函数体。由于p2返回的是另一个Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。

具体什么意思呢,看下面的例子:

上面代码中,调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolvedPromise是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolvereject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。


100ms后调用resolve函数,resolve函数内部将状态设为了resolved了,然后在本脚本其他同步惹任务都完成后执行then方法返回的回调函数,此时将value值传给then方法的回调函数。

如果一个接口访问时间超过400毫秒就算超时,用Promise如何解决
传统的解决思路设个定时器,设个全局变量data接受接口要返回的数据,如果400毫秒后定时器的全局data还未被赋值,说明接口请求超时,当然这种做法不够优雅,可以使用Promise来实现:


 

虽然看起来好像是解决了,但是怎么看怎么像愚蠢的解决方案嵌套了一层美丽的皮囊,下面结合Promiserace方法来更好的解决超时需求:


我要回帖

更多关于 函数调用可以作为一个函数的实参 的文章

 

随机推荐