我正在开发一个现有的Restify API,它有很多这个:
return newPromise().then(function(){
return Promise.resolve({foo:'bar'});
}).then(function(){
return Promise.resolve({rolo:'cholo'});
}):
现在,在promise中返回Promise.resolve
肯定是不必要的,但我想知道它不仅是多余的,而且如果它会损害API性能,因为最终Promise.resolve
可能会被调用两次值。
所以我的问题是 - 是否优化了ES6原生承诺,以便他们不会尝试解决已经解决的承诺?换句话说,内部API是否避免调用Promise.resolve(Promise.resolve(x))
?
答案 0 :(得分:3)
我无法谈论任何实现,但需要承诺的ES6规范seems to have a bug及其结果值每次都要解析。
答案 1 :(得分:2)
我不能谈论内部实现,但性能特征看起来大致相当 直接返回值对于Native Promises来说快2倍,对Bluebird来说要快1.1倍。这是我写的基准脚本:
<强>蓝鸟强>
var suite = new Benchmark.Suite;
suite
.add('Inner Resolve', {
name: "Bluebird Inner Resolve",
defer: true,
fn: function (deferred) {
return Promise.resolve("a")
.then(() => Promise.resolve("b"))
.then(() => deferred.resolve());
}
})
.add('Bluebird Inner Return', {
name: "Bluebird Inner Return",
defer: true,
fn: function (deferred) {
return Promise.resolve("a")
.then(() => "b")
.then(() => deferred.resolve());
}
})
.on('cycle', (event) => console.log(String(event.target)))
.on('complete', function onComplete () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({ 'async': true });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.4.0/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.0/benchmark.min.js"></script>
&#13;
<强>本地强>
var suite = new Benchmark.Suite;
suite
.add('Native Inner Resolve', {
name: "Native Inner Resolve",
defer: true,
fn: function (deferred) {
return Promise.resolve("a")
.then(() => Promise.resolve("b"))
.then(() => deferred.resolve());
}
})
.add('Native Inner Return', {
name: "Native Inner Return",
defer: true,
fn: function (deferred) {
return Promise.resolve("a")
.then(() => "b")
.then(() => deferred.resolve());
}
})
.on('cycle', (event) => console.log(String(event.target)))
.on('complete', function onComplete () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({ 'async': true });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.0/benchmark.min.js"></script>
&#13;
您可以在此处查看Chrome的实施(https://github.com/v8/v8/blob/4.3.66/src/promise.js#L167);一些簿记似乎是在Promise.resolve中完成的,但它并没有显着影响性能。
答案 2 :(得分:0)
Promise.resolve()
是一个目的有限的辅助函数,因此我不会过多地阅读其行为或性能,或者将其与承诺链接或实现中的解决方案中的内容联系起来。< / p>
FWIW,在我尝试过的所有浏览器实现中(包括Safari),我发现以下情况属实:
var p = new Promise(function() {});
console.log(Promise.resolve(p) == p);
这意味着它只会在传递承诺时返回传入的内容。冗余代码在JS中永远不会自由,但这是最小的。
这也意味着它在解决过程中的后期影响不大,因为它不会对分辨率链做出额外的承诺。
原来这种行为是explicitly specified(如果IsPromise(x)基本上返回x; 。
我们应该不必要地调用Promise.resolve()
,因为它是多余的,而不是因为任何真正的性能问题。