Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
通过Promise + setTimeout,实现JavaScript 的同步延迟简单示例,希望能够帮助你!!!。
过去在写 JavaScript 使用的同步延迟时,都是用非同步的 setTimeout 加上 callback 来实现,但如果有很多个任务或流程要执行,就得用上一大堆的 callback,然而 JavaScript 里的 Promise ,刚好就可以用来解决同步与非同步的问题,让整个延迟的过程可以很漂亮简洁且同步的「串」在一起。
一般来说 JavaScript 里面有分成同步 sync 和非同步 async,在同步模式下,每个任务必须按照顺序执行,后面的任务必须等待前面的任务执行完成,非同步模式则相反,后面的任务不用等前面的,各自执行各自的任务,例如setTimeout、setInterval都是这种模式。
如果 JavaScript 写成下面这样,结果并不会如果们预期的「等待一秒后出现 A,出现 A 后等待一秒再出现 B」,反而是等待一秒后 A、B 同时出现,所以变成传统在实作的时候,就要写很多的 callback 来满足同步的情况。
为了解决同步非同步的问题,我开始学习 Promise,刚接触 Promise 的时候实在是有点头昏脑胀,因为网路上的资料很多,但总找不到一个合适的范例展示,导致一直没办法深入理解,后来终于找到了几个合适的教程,也让我终于踏入了 Promise 的世界。
简单来说,Promise 就是「承诺」,可以想像成 A 承诺 B 要去办事,办完之后才会回报结果,而这个结果只有两种状况:成功与失败,不会有处于成功失败不明的中间状况。
所以换成程式的讲法,要使用 Promise,一开始要先 new 一个 Promise 对象实例,其中的建构式包含两个参数:resolve ( 成功 ) 与 reject ( 失败 )。
基本创建 Promise 的方法如下,resolve 在函式或流程成功,或有合法值的状况下会执行,reject 则是在失败或有错误的时候会执行,resolve 和 reject 都有一个回传值,可将这个会传值透过.then传给下一个流程。
大概知道用法之后,先来个简单的例子,建立一个 delay 的流程,流程裡有个setTimeout,在延迟一秒后,将 resolve 成功的值通过.then传下去。
不过这样只有写,跟纯粹setTimeout的结果看起来没什麽差异,因为只延迟了一次而已,现在换个例子,让显示的文字延迟三次,每次都延迟一秒,如果是传统setTimeout的写法就会像下面这样:三个流程 + 两个 callback,不仅越来越难阅读,维护成本相对也越来越高。
如果换成 Promise 的做法,就可以把 setTimeout 放到 Promise 里面,同时可以设定一个变数作为延迟的毫秒数,接下来就可以使用.then来做串接,在每一个 then 里头,再 return 一个 Promise 实例,就可以继续使用.then串接下去,实际完成之后,应该就会看到 123 依序隔一秒才出现,写法上也就更为清楚简洁。
当 resolve 有合法值的时候,可将这个值传递下去使用,但 resolve 只能有一个回传值 (resolve(value)),所以如果有两个以上,则必须通过数组来传递,举例来说 delay 有两个参数,第一个参数是显示的文字,第二个则是延迟的秒数,透过resolve([r,s]);就能不断地将值传递下去,结果就会是先显示「a 0」,延迟一秒后显示「b 1000」,延迟两秒后显示「c 2000」。
以上就是通过 Promise + setTimeout 所实现的同步延迟,但在 ES7 开始其实有 async、await、delay 的用法 ( 听说用过就会爱上 ),就等浏览器全面支持后,应该就可以更方便的使用了!
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
下一篇