Javascript 这种承诺嵌套是一种良好的实践吗?
我只是想知道,像本例中那样嵌套承诺是否被视为良好实践,或者是否有更好的替代方案Javascript 这种承诺嵌套是一种良好的实践吗?,javascript,promise,nested,Javascript,Promise,Nested,我只是想知道,像本例中那样嵌套承诺是否被视为良好实践,或者是否有更好的替代方案 getDatabaseModel.searchId(idNoms).then(function([noms, elements]) { getDatabaseModel.getLocalisations().then(function(localisations){ getDatabaseModel.getStates().then(function(states){
getDatabaseModel.searchId(idNoms).then(function([noms, elements]) {
getDatabaseModel.getLocalisations().then(function(localisations){
getDatabaseModel.getStates().then(function(states){
//Some code
})
})
})
承诺是为了避免地狱,但他们也不太擅长。人们喜欢承诺,直到他们发现异步/等待。完全相同的代码可以用async/await重新编写
async getModel(idNoms){
const [noms, elements] = await getDatabaseModel.searchId(idNoms);
const localisations = await getDatabaseModel.getLocalisations();
const state = await getDatabaseModel.getStates():
// do something using localisations & state, it'll work
}
getModel(idNoms);
学习异步/等待在我看来,阅读和理解有点难。与此相比:
getDatabaseModel.searchId(idNoms)
。然后(([noms,elements])=>getDatabaseModel.GetLocalizations()
.then(本地化=>getDatabaseModel.getStates());
正如@deceze指出的,有两件事需要注意:
- 这些函数按顺序调用
- 它们似乎并不相互依赖,因为根本不使用
、noms
和元素
本地化
承诺。所有您都可以随心所欲地混搭:
//同时调用'searchId'和'getState'
//在'searchId'完成后调用'GetLocalizations'
//等待一切结束
我保证([
getDatabaseModel.searchId(idNoms)。然后([noms,elements])=>getDatabaseModel.getLocalizations(),
getDatabaseModel.getStates()
])。然后(([result1,result2])=>console.log('done');
//同时呼叫所有3个
//等待一切结束
我保证([
getDatabaseModel.searchId(idNoms),
getDatabaseModel.GetLocalizations(),
getDatabaseModel.getStates(),
])。然后(([result1,result2,result3])=>console.log('done');
显然,你的承诺是独立的。因此,您应该使用使其以最高性能并行运行
Promise.all()方法将一组promises作为输入,
并返回解析为结果数组的单个承诺
投入的承诺
例如,假设每个承诺都需要1s,那么它总共应该是3s,但是对于promise.all
,实际上它总共只需要1s
var tick=Date.now();
const log=(v)=>console.log(`${v}\n经过:${Date.now()-tick}`);
日志(“凝视…”);
var fetchData=(name,ms)=>newpromise(resolve=>setTimeout(()=>resolve(name,ms));
var result=Promise.all(
[
获取数据(“searchById”,1000),
fetchData(“GetLocalizations”,1000),
fetchData(“getStates”,1000)
]);
结果。然后((值)=>{
日志(“完成…”);
console.log(值);
});代码>异步等待是你想要的。你正在重新创造回调地狱,而这正是承诺要避免的。将一个新的承诺返回到链中:a.b().then(函数(args){Return a.c();})。然后(函数(args){Return a.d();})。然后(…)
此外,调用看起来并不是真的相互依赖,所以您可能希望并行地触发它们,并累积结果:promise.all([a.b(),a.c(),a.d())。然后(函数)([b,c,d]){…})
wait
关键字很多人说,代码应该等到异步请求完成,然后再执行下一件事。虽然这些承诺是独立的。所以promise.all
比:)我理解你的意思,并不是我不知道promise.all,根据OP的代码,我确实看到了它们不是相互依赖的,但我也注意到OP之所以嵌套它们是因为某种原因,否则他不会嵌套它们并连续调用3个承诺,因此等待,我也将结果放入变量中。@PhongSeems like Promise.all()对我来说,这是最好的方法,但我相信你的例子将来会有帮助的!非常感谢你的帮助!
var searchById = getDatabaseModel.searchId(idNoms);
var getLocalisations = getDatabaseModel.getLocalisations();
var getStates = getDatabaseModel.getStates();
var result = Promise.all([searchById, getLocalisations, getStates]);
result.then((values) => {
console.log(values);
});