Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 这种承诺嵌套是一种良好的实践吗?_Javascript_Promise_Nested - Fatal编程技术网

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);
});