我通过节点应用程序使用mondora/asteroid通过承诺模式使用Meteor DDP。
我将以下代码从回调样式重写为承诺样式,但我仍然坚持如何展平它。
asteroid.call('Pony.search', { params })
.then(res => {
if (res.length === 1) {
// something
asteroid.call('Pony.finish', { params })
// this part feels wrong
.then(res => {
// something else
});
} else {
// nope
}
})
.catch(err => {
console.error(err);
});
还有第二个asteroid.call
&第一个承诺响应中的then
是一个承诺。这部分感觉不对,就像它应该是扁平的而不是嵌套但我不知道如何到达那里。
编辑:
结束使用这样的事情(仍然没有决定是否有第一个然后检查if length === 1
并可能立即拒绝它。任何人都知道什么是最佳做法?
asteroid.call('Pony.search', { params })
.then(res => res.length === 1 ? res : Promise.reject())
.then(res => asteroid.call('Pony.finish', { res[0].something }))
.then(res => {
// do something
})
.catch(err => {
// handle the no found
console.error(err);
});
答案 0 :(得分:1)
而不是嵌套回调,链接承诺与.then()
注意:
我不确定你正在使用什么Promise库,但是想法是从第一个.then()返回被拒绝的promise,如果有错误,否则你会返回一个成功的promise。然后,promise库将为您处理错误处理,如果存在被拒绝的promise,则转到catch块。
asteroid.call('Pony.search', { params })
.then(res => {
res.length === 1 ? return asteroid.call('Pony.finish', { params }) : Promise.reject();
})
.then(res => {
//do stuff here
})
.catch(err => {
console.error(err);
});
编辑:
唯一的问题是当您需要同时访问承诺中的返回值的两个时。当你扁平化承诺链时,你将失去对先前承诺的结果的访问权。
您有几个选择:
如果确实需要以前的值
2a上。而且你不关心执行的顺序,然后使用Promise.all([promise1, promise2])
2B。而且你确实关心执行的顺序,那么你必须像你最初那样使用嵌套的promises。
答案 1 :(得分:0)
如果promises是嵌套的,则promises和callback之间没有区别。
尝试更改代码以使用保证链:
asteroid.call('Pony.search', { params })
.then(res => {
if (res.length === 1) {
// something
let p1 = asteroid.call('Pony.finish', { params });
return p1;
}
else {
// nope
}
})
.then (function SomeThingElse(res2){
// something else
// res2 is return value from nested asteroid.call
})
.catch(err => {
console.error(err);
});
由于第一个解析处理程序返回Promise p1
,因此链中的下一个函数(function SomeThingElse
)的调用将推迟到p1
为resolved
。
现在扩展这个例子:
asteroid.call('Pony.search', { params })
.then(res => {
if (res.length === 1) {
// something
let p1 = asteroid.call('Pony.finish', { params });
return p1;
}
else {
// nope
}
})
.then (function SomeThingElse(res2){
// something else
// res2 is return value from nested asteroid.call
})
.then (function AnotherFunc(res3){
})
.catch(err => {
console.error(err);
});
如果SomeThingElse
返回Promise
,则AnotherFunc
的调用会延迟,直到该承诺得到解决。
如果SomeThingElse
不返回Promise
,则会立即使用与收到的“SomeThingElse”相同的参数调用AnotherFunc
。换句话说,当p1被解析时,SomeThingElse
和AnotherFunc
都会被调用。