Javascript 如何有效地使用JS Promiss?
从表面上看,我没有在JS中正确使用承诺 我有3个异步相互依赖函数,如下所示: func1、func2和Func3Javascript 如何有效地使用JS Promiss?,javascript,promise,Javascript,Promise,从表面上看,我没有在JS中正确使用承诺 我有3个异步相互依赖函数,如下所示: func1、func2和Func3 func1返回func2使用的单个结果 func2还返回一个结果 func3使用func1和func2的结果 所以func3必须同时等待func1和func2,而func2只能等待func1 这是我能够创作的JS提琴,它很管用,但是阅读3个一起使用的乱七八糟的东西只不过是一件小事。实施这种连锁经营的正确方式是什么 函数func1(){ 返回新承诺(功能(解决、拒绝){ setT
- func1返回func2使用的单个结果
- func2还返回一个结果
- func3使用func1和func2的结果
函数func1(){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
决议(10);
}, 1000);
});
}
函数func2(返回1){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解决(返回1+20);
}, 1000);
});
}
函数func3(val1,val2){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解析(val1+val2);
}, 1000);
});
}
func1().then(函数(结果){
func2(结果)。然后(函数(结果2){
func3(结果,结果2)。然后(函数(最终结果){
控制台日志(最终结果);
},函数(err){
控制台日志(err);
});
});
}).catch(函数(err){
控制台日志(err);
});代码>使用just promises,您可以使用闭包范围并嵌套您的承诺(这就是您正在做的),也可以将多个结果作为如下对象传递:
func1()
.then((result) => {
return func2(result).then((result2) => ({result, result2}));
})
.then(({result, result2}) => {
return func3(result, result2);
});
async function fn() {
const result = await func1();
const result2 = await func2(result);
const result3 = await func3(result, result2);
return result3;
}
fn().then((result3) => console.log(result3));
或者,您可以将结果存储在所有承诺之外的范围内:
let result;
func1()
.then((_result) => {
result = _result;
return func2(result);
})
.then((result2) => {
return func3(result, result2);
});
如果您的环境支持,您可以这样重写它:
func1()
.then((result) => {
return func2(result).then((result2) => ({result, result2}));
})
.then(({result, result2}) => {
return func3(result, result2);
});
async function fn() {
const result = await func1();
const result2 = await func2(result);
const result3 = await func3(result, result2);
return result3;
}
fn().then((result3) => console.log(result3));
如果您的环境支持生成器,则可以使用库来创建co例程:
const fn = co.wrap(function*() {
const result = yield func1();
const result2 = yield func2(result);
const result3 = yield func3(result, result2);
return result3;
});
fn().then((result3) => console.log(result3));
使用just promises,您可以使用闭包范围并嵌套您的承诺(这就是您正在做的),也可以将多个结果作为如下对象传递:
func1()
.then((result) => {
return func2(result).then((result2) => ({result, result2}));
})
.then(({result, result2}) => {
return func3(result, result2);
});
async function fn() {
const result = await func1();
const result2 = await func2(result);
const result3 = await func3(result, result2);
return result3;
}
fn().then((result3) => console.log(result3));
或者,您可以将结果存储在所有承诺之外的范围内:
let result;
func1()
.then((_result) => {
result = _result;
return func2(result);
})
.then((result2) => {
return func3(result, result2);
});
如果您的环境支持,您可以这样重写它:
func1()
.then((result) => {
return func2(result).then((result2) => ({result, result2}));
})
.then(({result, result2}) => {
return func3(result, result2);
});
async function fn() {
const result = await func1();
const result2 = await func2(result);
const result3 = await func3(result, result2);
return result3;
}
fn().then((result3) => console.log(result3));
如果您的环境支持生成器,则可以使用库来创建co例程:
const fn = co.wrap(function*() {
const result = yield func1();
const result2 = yield func2(result);
const result3 = yield func3(result, result2);
return result3;
});
fn().then((result3) => console.log(result3));
编辑:我误解了要求。SimpleJ给出的答案是正确的
然后
回调中返回的值本身是可启用的。换句话说,您可以通过从返回下一个函数,然后从上一个函数的回调返回下一个函数,从而按顺序完成承诺
而不是
func1()。然后(函数(结果){
func2(结果)。然后(函数(结果2){
func3(结果,结果2)。然后(函数(最终结果){
控制台日志(最终结果);
},函数(err){
控制台日志(err);
});
});
}).catch(函数(err){
控制台日志(err);
});代码>编辑:我误解了要求。SimpleJ给出的答案是正确的
然后
回调中返回的值本身是可启用的。换句话说,您可以通过从返回下一个函数,然后从上一个函数的回调返回下一个函数,从而按顺序完成承诺
而不是
func1()。然后(函数(结果){
func2(结果)。然后(函数(结果2){
func3(结果,结果2)。然后(函数(最终结果){
控制台日志(最终结果);
},函数(err){
控制台日志(err);
});
});
}).catch(函数(err){
控制台日志(err);
});代码>我投票结束这个问题,因为关于如何改进/重新设计工作代码的建议请求属于CodeReview.stackexchange.com。我不确定还有多少改进空间。我看不到多余的代码,它直接表达了设计需求。您是否需要将其推广到N个函数,其中每个函数都需要得到前面所有函数的结果?您可能对此感兴趣。这涵盖了在链接承诺时访问多个先前结果的各种选项。@Barmar链接代码对我来说非常难以阅读,因为它的作用域与回调相同。我怀疑我搞笑的承诺是错误的。别忘了回复你的承诺!在调用func2()
和func3()
之前,应该有return
。否则,底部的catch
只能捕获func1()
中发生的错误。我投票将此问题作为离题问题结束,因为关于如何改进/重新设计工作代码的建议请求属于CodeReview.stackexchange.com。我不确定是否有多少改进空间。我看不到多余的代码,它直接表达了设计需求。您是否需要将其推广到N个函数,其中每个函数都需要得到前面所有函数的结果?您可能对此感兴趣。这涵盖了在链接承诺时访问多个先前结果的各种选项。@Barmar链接代码对我来说非常难以阅读,因为它的作用域与回调相同。我怀疑我搞笑的承诺是错误的。别忘了回复你的承诺!在调用func2()
和func3()
之前,应该有return
。否则,底部的catch
只能捕获func1()
中发生的错误。但是func3需要来自func1和func2的结果,在您的解决方案中,它只接受来自func2的结果。是吗?啊,是的,我错过了。我将调整答案。但是func3需要来自func1和func2的结果,在您的解决方案中,它只接受来自func2的结果。是吗?啊,是的,我错过了。我会调整答案。我喜欢异步等待,这样更干净。然而,将结果作为对象表示法传递对我来说似乎是一个糟糕的设计,因为这将表明func2只会被func3使用,因为它本质上是将值从func1传递到func3