使用 Promise 按顺序调用函数
Using Promises to Call Functions In Sequence
我有以下代码,由三个函数和一个回调函数组成。
我在这里面临的挑战是:
我必须按此顺序打印 A ,然后是 B ,然后是 C
我试过下面的代码,但它总是打印 C 、 B ,然后是 A
我知道这是由于 setTimeout A > setTimeout B > setTimeout C 造成的。
但是有什么办法可以让我只有在得到A的响应时才调用B,只有在得到B的响应时才调用C。
请帮忙,因为我被困在这里
const print = (err, contents) => {
if (err) console.error(err)
else console.log(contents)
}
const opA = (cb) => {
setTimeout(() => {
cb(null, 'A')
}, 500)
}
const opB = (cb) => {
setTimeout(() => {
cb(null, 'B')
}, 250)
}
const opC = (cb) => {
setTimeout(() => {
cb(null, 'C')
}, 125)
}
我试过的代码:
function promisifyA(){
return new Promise( (resolve,reject) => {
resolve(opA(print));
});
}
function promisifyB(){
return new Promise( (resolve,reject) => {
resolve(opB(print));
});
}
function promisifyC(){
return new Promise( (resolve,reject) => {
resolve(opC(print));
});
}
promisifyA().then(() => {
return promisifyB();
}).then(() => {
return promisifyC();
});
你应该只在函数完成后才 resolve() 。
即
function promisifyA(){
return new Promise( (resolve,reject) => {
opA((err, val) => {
print(val);
resolve()
});
});
}
在第一种(非承诺)方法中,我想你是这样调用你的函数的:
opA(print);
opB(print);
opC(print);
很明显,所有三个函数 opA
、opB
和 opC
都被一个接一个地立即调用。以下是如何将它们作为您传递的回调 的 一部分进行调用:
const print = (err, contents) => {
if (err) console.error(err)
else console.log(contents)
}
const opA = (cb) => {
setTimeout(() => {
cb(null, 'A')
}, 500)
}
const opB = (cb) => {
setTimeout(() => {
cb(null, 'B')
}, 250)
}
const opC = (cb) => {
setTimeout(() => {
cb(null, 'C')
}, 125)
}
opA((err, contents) => {
print(err, contents);
opB((err, contents) => {
print(err, contents);
opC(print);
});
});
虽然这会实现你想要的,但这也导致了所谓的“回调地狱”。如果你重复这个模式,缩进只会不断增加...
这就是 promises 可以提供帮助的地方。首先承诺 setTimeout
:
const delay = (ms, value) => new Promise(resolve =>
setTimeout(() => resolve(value), ms)
);
const output = console.log;
const error = console.error;
const opA = () => delay(500, 'A');
const opB = () => delay(250, 'B');
const opC = () => delay(125, 'C');
opA().then(output)
.then(opB)
.then(output)
.then(opC)
.then(output)
.catch(error);
我有以下代码,由三个函数和一个回调函数组成。 我在这里面临的挑战是: 我必须按此顺序打印 A ,然后是 B ,然后是 C
我试过下面的代码,但它总是打印 C 、 B ,然后是 A
我知道这是由于 setTimeout A > setTimeout B > setTimeout C 造成的。
但是有什么办法可以让我只有在得到A的响应时才调用B,只有在得到B的响应时才调用C。
请帮忙,因为我被困在这里
const print = (err, contents) => {
if (err) console.error(err)
else console.log(contents)
}
const opA = (cb) => {
setTimeout(() => {
cb(null, 'A')
}, 500)
}
const opB = (cb) => {
setTimeout(() => {
cb(null, 'B')
}, 250)
}
const opC = (cb) => {
setTimeout(() => {
cb(null, 'C')
}, 125)
}
我试过的代码:
function promisifyA(){
return new Promise( (resolve,reject) => {
resolve(opA(print));
});
}
function promisifyB(){
return new Promise( (resolve,reject) => {
resolve(opB(print));
});
}
function promisifyC(){
return new Promise( (resolve,reject) => {
resolve(opC(print));
});
}
promisifyA().then(() => {
return promisifyB();
}).then(() => {
return promisifyC();
});
你应该只在函数完成后才 resolve() 。 即
function promisifyA(){
return new Promise( (resolve,reject) => {
opA((err, val) => {
print(val);
resolve()
});
});
}
在第一种(非承诺)方法中,我想你是这样调用你的函数的:
opA(print);
opB(print);
opC(print);
很明显,所有三个函数 opA
、opB
和 opC
都被一个接一个地立即调用。以下是如何将它们作为您传递的回调 的 一部分进行调用:
const print = (err, contents) => {
if (err) console.error(err)
else console.log(contents)
}
const opA = (cb) => {
setTimeout(() => {
cb(null, 'A')
}, 500)
}
const opB = (cb) => {
setTimeout(() => {
cb(null, 'B')
}, 250)
}
const opC = (cb) => {
setTimeout(() => {
cb(null, 'C')
}, 125)
}
opA((err, contents) => {
print(err, contents);
opB((err, contents) => {
print(err, contents);
opC(print);
});
});
虽然这会实现你想要的,但这也导致了所谓的“回调地狱”。如果你重复这个模式,缩进只会不断增加...
这就是 promises 可以提供帮助的地方。首先承诺 setTimeout
:
const delay = (ms, value) => new Promise(resolve =>
setTimeout(() => resolve(value), ms)
);
const output = console.log;
const error = console.error;
const opA = () => delay(500, 'A');
const opB = () => delay(250, 'B');
const opC = () => delay(125, 'C');
opA().then(output)
.then(opB)
.then(output)
.then(opC)
.then(output)
.catch(error);