JavaScript作为运行在浏览器中的语言,天生对事件的处理就有异步运行的特性。异步的写法主要是回调函数,而多个回调互相调用写起来比较难看,可以查看回调地狱相关的问题。

Promise的出现解决了一部分问题。它通过then的函数将成功后要执行的操作按顺序串联在一起。

let timeout = () => new Promise((resolve, reject) => setTimeout(resolve, 1000))

timeout().then(() => {
    console.log(1)
}).then(() => {
    console.log(2)
}).then(() => {
    console.log(3)
})

这样就会在一秒后同时输出123。

如果我们想每隔一秒输出一个数字该怎么办?比如我有5个一秒延时的timeout任务,将他们按顺序依次执行,总耗时5秒钟。

Promise的then操作的返回值可以是一个新的Promise,这样后续的Promise操作可以串联起来。

let timeout = (index) => new Promise((resolve, reject) => setTimeout(() => {
    resolve(index)
}, 1000))

let start = Promise.resolve(0)

for (let i = 1; i < 6; i++) {
    start = start.then((res) => {
        console.log(res)
        return timeout(i)
    })
}

或者

let timeout = (index) => new Promise((resolve, reject) => setTimeout(() => {
    resolve(index)
}, 1000))

;(async () => {
    for (let i = 0; i < 6; i++) {
        await timeout(i).then((res) => console.log(res))
    }
})()

被async修饰的函数会在await等待Promise执行完毕,而不是立即开始下一个循环。这个语法才真正将异步函数的写法转换为同步语法,理解起来就像同步语言那么简单。

Promise提供了Promise.allPromise.race方法,简化对Promise列表状态的监控。

Promise异步的方法与async await的配合可以达到同步编程的效果,JavaScript的语法特性越来越好,发展的很快,要学习的还有很多。

原文链接:https://marskid.net/2018/11/11/async-promise/