ES6 Promise的使用详解

Promise是ES6的一个用于处理异步操作的库。他本身是没有异步功能的,只是更方便异步操作而已。如果你用过类似rxjava的库的话,你就很容易明白。不过比rxjava简单的多。没用过也没关系。

在前端应用种,我们经常需要发送网络请求。有可能通过一个url请求到另一个url,在通过这个url请求到第三个url。可能嵌套个4 5层。例如下面的代码,这样的代码是非常难以维护的。Promise就可以专门用来处理这种问题。

$ajax{
 //100行逻辑处理
 $ajax{
 	//100行逻辑处理
 	$ajax{
 		//100行逻辑处理
		 $ajax{
			 //100行逻辑处理
			 $ajax{
				 //100行逻辑处理
			}
		 }
	 }
	 }
}

Promise入门例子

我们先写一个嵌套的例子。然后用Promise进行改造。
下面这个代码就是所谓的回调地狱。如果代码很多,那么将非常的混乱。

setTimeout(()=>{
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    setTimeout(()=>{
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        console.log("Hello JS")
        setTimeout(()=>{
            console.log("Hello Python")
            console.log("Hello Python")
            console.log("Hello Python")
            console.log("Hello Python")
            console.log("Hello Python")
        },1000)
    },1000)
},1000)

我们用Promise就可以写成下面的代码。
这代码怎么还变多了?代码多少不是关键,关键是代码结构变得清晰了。而且变成了链式编程。也就是嵌套的问题没有了,现在所以的代码都处在同一级上,至少从结构上来说是这样。
代码多不是问题,后面介绍简写的写法。简写之后只能用一个词形容,就是优雅。后面介绍。

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve()
    }, 1000)
}).then(() => {
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    })
}).then(() => {
    console.log("Hello JS")
    console.log("Hello JS")
    console.log("Hello JS")
    console.log("Hello JS")
    console.log("Hello JS")
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    })
}).then(() => {
    console.log("Hello Python")
    console.log("Hello Python")
    console.log("Hello Python")
    console.log("Hello Python")
    console.log("Hello Python")
})

请求失败的情况,如果请求失败,可以调用reject方法,并且在catch处理错误。后面的操作都会中断。

new Promise((resolve, reject) => {
    setTimeout(() => {
       // resolve()
        reject("err message")
    }, 1000)
}).then(() => {
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
}).catch((err)=>{
    console.log(err);
})

还有一种处理错误的方式是使用then的第二个参数,可以直接处理错误的情况。

new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve()
        reject("err message")
    }, 1000)
}).then(() => {
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
    console.log("Hello World")
}, err => {
    console.log(err);
})

还可以使用Promise进行任务方便,分步操作。

//使用Promise进行多次处理,任务分解。
new Promise((resolve, reject) => {
    setTimeout(() => {
          resolve("aaa")
    }, 1000)
}).then(res => {
    console.log("第一次10行处理")
    return new Promise(resolve => {
        //对结果进行第一次处理
        resolve(res+"111")
    })
}).then(res=>{
    console.log("第二次10行处理")
    return new Promise(resolve => {
        //对结果进行第一次处理
        resolve(res+"222")
    })
}).then(res=>{
    console.log("第三次10行处理")
    return new Promise(resolve => {
        //对结果进行第一次处理
        resolve(res+"333")
    })
})

上面的写法可以简写成下面的样子,代码少了很多。

//使用Promise进行多次处理,任务分解。
new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("aaa")
    }, 1000)
}).then(res => {
    console.log("第一次10行处理")
    return Promise.resolve(res + "111")
}).then(res => {
    console.log("第二次10行处理")
    return Promise.resolve(res + "222")
}).then(res => {
    console.log("第三次10行处理")
    return Promise.resolve(res + "333")
})

处理错误的简写形式。

//还能进一步简写,Promise都不想写,这样已经非常舒服了
new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("aaa")
    }, 1000)
}).then(res => {
    console.log("第一次10行处理")
    return res + "111"
}).then(res => {
    console.log("第二次10行处理")
    return Promise.reject("err message")
}).then(res => {
    console.log("第三次10行处理")
    return res + "333"
}).catch(err=>{
    console.log("err message from second process")
})

监听多个请求的结束时机

有这样的需求,在两个请求都返回结果后,发生第三个请求。关键点就是我们怎么监听到前面两个请求什么时候结束。
Promise为我们提供了all方法来处理这个问题。
也是非常的简洁好用。

Promise.all([
    new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log("开始第一个请求")
            resolve("result1")
        },2000)

    }),
    new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log("开始第二个请求")
            resolve("result2")
        },1000)
    })
]).then(results=>{
    console.log(results[0])
    console.log(results[1])
    console.log("开始第三个请求")
})

你可能感兴趣的:(es6,rxjava,前端)