这两种处理顺序Promises的样式有什么区别

时间:2018-07-12 07:26:27

标签: javascript promise

当我们要依次执行几个然后一个函数时,这两种样式有什么区别?

1-要使用嵌套的话,

$http.get('api').then(function(){
    processBlocks(obj.data).then(function(){
        alert('it is done')
    });
});

2-拼合嵌套的话

$http.get('api').then(function(){
    return processBlocks(obj.data);
}).then(function(){
    alert('it is done')
});

很明显,第二个更具可读性,但是在性能上也有差异吗?

2 个答案:

答案 0 :(得分:3)

$http.get('api').then(function(){
    processBlocks(obj.data).then(function(){
        alert('it is done')
    });
});

在这种情况下,如果您这样连接另一个then

$http.get('api').then(function(){
    processBlocks(obj.data).then(function(){
        alert('it is done')
    });
}).then(function(){
alert('it is done')
});

如果processBlocks()引发异常,那没关系,下一个承诺将被触发,但是:

$http.get('api').then(function(){
    return processBlocks(obj.data);
}).then(function(){
    alert('it is done')
});

在这种情况下,如果第一个then失败,则该序列将被取消,并且在具有catch块的情况下,它将被触发

答案 1 :(得分:1)

在性能上可能会有细微的差异,因为传递给.then的函数与初始链接的Promise 链接在一起,当解释程序在该行上跨过初始Promise时。为了说明,当所有Promises都以扁平方式链接在一起时,第二个链接的expensiveFunctionThatReturnsFunc()立即运行 以便创建要放入.then链中的函数:< / p>

const resolveAfter = ms => new Promise(res => setTimeout(res, ms));

const expensiveFunctionThatReturnsFunc = () => {
  console.log('making fn...');
  // for (let i = 0; i < 999999999; i++) {}
  return () => console.log('resolving');
}

console.log('start');
resolveAfter(1000)
  .then(() => resolveAfter(1000))
  .then(expensiveFunctionThatReturnsFunc());

相反,当您嵌套。then时,expensiveFunctionThatReturnsFunc()仅在第一个Promise解析后运行:

const resolveAfter = ms => new Promise(res => setTimeout(res, ms));

const expensiveFunctionThatReturnsFunc = () => {
  console.log('making fn...');
  // for (let i = 0; i < 999999999; i++) {}
  return () => console.log('resolving');
}

console.log('start');
resolveAfter(1000)
  .then(() => {
    return resolveAfter(1000)
    .then(expensiveFunctionThatReturnsFunc());
  });

不过,在99%的情况下,这种事情的影响是完全不可察觉的。不用担心,最好只是使代码可读。