承诺的新事物;考虑promiseA()
和promiseB(a)
取决于第一个结果的情况,我想从两者中收集结果并执行第三个操作doSomething(a, b)
:
样式A(闭包/嵌套)
promiseA().then(function (resultA) {
return (promiseB(resultA).then(function (resultB) {
doSomething(resultA, resultB);
}));
});
样式B(返回值/链接)
promiseA().then(function (resultA) {
return Promise.all([resultA, promiseB(resultA)]);
}).spread(function (resultA, resultB) {
doSomething(resultA, resultB);
});
据我所知,这些是等价的:
promiseA
和promiseB
undefined
promiseA
或promiseB
被拒绝或doSomething
被拒绝,最终承诺将被拒绝。作为风格问题,风格B减少了缩进(厄运的金字塔)。
然而,风格B更难以重构。如果我需要引入中间版promiseA2(a)
和doSomething(a, a2, b)
,我需要修改3行(Promise.all
,spread
,doSomething
),这可能会导致错误(意外交换等),而Style AI只修改1行(doSomething
),变量名称清楚表明它是什么结果。在大型项目中,这可能很重要。
两种风格之间是否存在其他非功能性权衡?一个与另一个的内存分配更多/更少?事件循环周围有更多/更少的转弯?异常的堆栈跟踪更好/更差?
答案 0 :(得分:0)
我认为这两种方法之间的非功能性权衡并不那么重要:第二种方法在创建数组时会有一些开销,并传播相应的结果,并且会产生一个更多的承诺。但是在异步流程中,我认为这一切都可以忽略不计。
您主要担心的是重构的难易程度。
为此,我建议使用一组函数,并Model.where(id: params[:id_list]).destroy_all
覆盖它:
reduce
这个想法是[promiseA, promiseB, doSomething].reduce( (prom, f) =>
prom.then( (res = []) => ( f(...res) || prom).then( [].concat.bind(res) ) )
, Promise.resolve() );
// Sample functions
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function promiseA() {
console.log('promiseA()');
return wait(500).then(_ => 13);
}
function promiseB(a) {
console.log('promiseB(' + a + ')');
return wait(500).then(_ => a + 2);
}
function doSomething(a, b) {
console.log('doSomething(' + a + ',' + b + ')');
}
回调链中的下一个函数将所有先前的结果作为参数传递。因此,如果要在链中注入一个promise-returns函数,则需要将其插入到数组中。不过,您需要注意传递的参数:它们在此解决方案中是累积的,因此then
不是规则的例外。
如果另一方面,您只希望doSomething
获得所有结果,并且只将最新结果传递给每个中间函数,那么代码将如下所示:
doSomething