let str1 = 'str1 ';
const func1=(str1)=>new Promise((resolve,reject)=>{
resolve(str1 + 'str2 ');
})
const func2=(str2)=>new Promise((resolve,reject)=>{
resolve(str2 + 'str3 ');
})
const func3=(str3)=>new Promise((resolve,reject)=>{
resolve(str3 + 'str4 ');
})
可能不怎么有价值的一篇。
因为我不求甚解,之前的代码经常在使用Promise的前提,创造了新式的“回调地狱”(函数作为参数层层嵌套)
错误示例如下(其实并不算错,只是把洗衣机用作了洗衣盆):
func1(str1)
.then(res=>{
func2(res)
.then(res=>{
func3(res)
.then(res=>{
console.log(res);
console.log("==================");
})
})
})
结果是正确结果,但,这就还是回调地狱,只不过披上了一层Promise的皮。
下面是正确的链式调用:
func1(str1)
.then(res=>func2(res))
.then(res=>func3(res))
.then(res=>{
console.log(res);
console.log("==================");
})
MDN关于“链式调用”的讲解如下:
"then
方法返回一个 Promise
对象,其允许方法链。
你可以传递一个匿名函数给 then
,并且,如果它返回一个 Promise
,一个等价的 Promise
将暴露给后续的方法链。"
代码讲解:
func1方法接收str1返回一个Promise对象,.then的第一个参数进入resolve分支,将第一个res传递给func2。
而func2也返回了一个Promise对象,故第一处then写成then(res=>func2(res)),通过箭头函数返回方法调用来直接返回【func2(res)所返回的Promise对象】,因此满足了条件——传给then的一个匿名函数,且这个匿名函数返回一个Promise。
那么,便可以直接在.then(res=>func2(res))的后面继续写上.then(res=>func3(res)),这里的第二个.then所捕获到的Promise对象,正是func2(res)所返回的。
完整的demo代码
let str1 = 'str1 ';
const func1=(str1)=>new Promise((resolve,reject)=>{
resolve(str1 + 'str2 ');
})
const func2=(str2)=>new Promise((resolve,reject)=>{
resolve(str2 + 'str3 ');
})
const func3=(str3)=>new Promise((resolve,reject)=>{
resolve(str3 + 'str4 ');
})
func1(str1)
.then(res=>{
func2(res)
.then(res=>{
func3(res)
.then(res=>{
console.log(res);
console.log("==================");
})
})
})
func1(str1)
.then(res=>func2(res))
.then(res=>func3(res))
.then(res=>{
console.log(res);
console.log("==================");
})
在线demo地址:https://jsrun.net/Z26Kp/edit
在线demo截图
========================================
2020-12-03补充,在axios里,可以这样链式调用
function test(){
axios.post(GLOBAL_URL.addTag, { 参数 })
.then(res => {
res = res.data;
if (res.code === "200") {
//注意下面的这句return
return axios.post(GLOBAL_URL.updateTarcileMidTag, { 参数})
} else {
}
})
.then(res => {
if (res) {//这里要加个if(res)
res = res.data;
if (res.code === "200") {
} else {
}
}
})
}