是否有一种简短的内置方式来进行水平承诺链接?
连锁步骤的常用方法是:
(async()=>1)().then(_=>{
//etc..
return _+_
}).then(_=>{
//etc..
return _*_
}).then(_=>{
//etc..
return alert(_) // alert 4
})
所以我使用助手避免重复then
:
F=(...args)=>{
let p=args[0]
for(let x=1; x<args.length;++x){
p=p.then(args[x])
}
}
F((async()=>1)(), _=>{
//etc..
return _+_
}, _=>{
//etc..
return _*_
}, _=>{
//etc..
return alert(_)
})
另一种变形,它重载原型并允许第二个参数:
Promise.prototype.thenAll = function(...args){
let p = this;
args.forEach(_=>p=p.then(_[0], _[1]))
}
;(async()=>1)().thenAll([_=>{
//etc..
return _+_
}], [_=>{
//etc..
return _*_
}], [_=>{
//etc..
return alert(_)
}])
但是,有没有一种内置的方法来做类似于这些的事情?
答案 0 :(得分:3)
正如其他人所说,没有内置的方法可以做到这一点。以下代码可能会引起关注。
有一个称为“提升”的概念,您可以将函数转换为处理包装值的函数。在这种情况下承诺。它看起来像这样:
const lift = (fn) => (promise) => promise.then(fn);
还有一个想法是将一系列功能链接在一起,将它们相互组合起来。像这样:
const chain = (...fns) => (value) => fns.reduce((result, fn) => fn(result), value)
这些工具允许您将代码重写为:
chain(
lift(_=>++_),
lift(_=>_*=_),
lift(_=>alert(_))
)((async()=>1)())
按预期警告4。
我对你使用++_
和_*=_
感到有些困惑,因为它们意味着你希望改变变量。由于您的代码的结构如何,因此可以更好地显示使用_+1
和_*_
答案 1 :(得分:1)
使用Array.reduce()
,您可以使用以下静态函数将一系列函数组合到一个promise链中:
function series (initial, ...callbacks) {
return callbacks.reduce(
(chain, callback) => chain.then(callback),
Promise.resolve(initial)
)
}
series(1, _=>_+1, _=>_*_, alert)
&#13;
为方便起见,您可以将其定义为Promise.series()
,如下所示:
Object.defineProperty(Promise, 'series', {
configurable: true,
value: function series (initial, ...callbacks) { ... },
writable: true
})
最后,在ES2017中,您也可以使用async
/ await
来编写它:
async function series(initial, ...callbacks) {
let value = await initial
for (const callback of callbacks) {
value = await callback(value)
}
return value
}
series(1, _=>_+1, _=>_*_, alert)
&#13;
答案 2 :(得分:1)
您可以使用rest参数将N
函数传递给函数,该函数按顺序返回要调用的Promise
,并将先前的Promise
值设置为传递给当前函数调用的参数直到没有元素使用async/await
保留在数组中并重复安排相同的过程
const a = n => new Promise(resolve =>
setTimeout(resolve, Math.floor(Math.random() * 1000), ++n));
const b = n => new Promise(resolve =>
setTimeout(resolve, Math.floor(Math.random() * 1000), n * n));
const F = async(n, ...fns) => {
try {
while (fns.length) n = await fns.shift()(n);
alert(n);
} catch (err) {
throw err
}
return n
}
F(1, a, b)
.then(n => console.log(n))
.catch(err => console.error(err));
&#13;
答案 3 :(得分:-1)
鉴于Question的代码是同步的,您可以使用问题
中的代码
((_) => (_++, _*=_, alert(_)) )(1)
&#13;
或使用async/await
(async(_) => (_ = await _, _++, _ *= _, alert(_)))(Promise.resolve(1))
&#13;