我受过Java训练的头脑仍然难以理解Javascript和承诺的使用。我有以下设置:
function foo() {
return Promise.resolve('foo');
}
函数foo返回函数bar和baz中所需的值:
function bar(foo) {
// process and use foo
return Promise.resolve('bar');
}
function baz(foo,bar) {
return Promise.resolve(foo+bar);
}
由于baz()
使用foo()
和bar()
的结果,我必须将它们链接起来:
foo()
.then((foo)=>{
return bar(foo)
.then((bar)=>{
return baz(foo,bar);
})
})
.then(console.log);
根据baz
后面的函数数量(也需要前面函数的结果),这似乎很快变得丑陋。
是否有另一种方式,更容易阅读/更直接?
答案 0 :(得分:0)
只需使用async / await:
;(async ()=> {
const fooResult = await foo()
console.log(await baz(fooResult, await bar(fooResult)))
})()
答案 1 :(得分:0)
不需要将来的Async语法。我有点害怕这个功能会被滥用。
const
foo = () =>
Promise.resolve('foo')
, bar = foo =>
Promise.resolve('bar')
, baz = (foo, bar) =>
Promise.resolve(foo + bar)
, delay = (ms, p) =>
new Promise(res =>
setTimeout(res, ms, p))
, randWait = p =>
delay(Math.random() * 5000, p)
, log = a => console.log(a) || a
, str = a =>
JSON.stringify(a, null, 2)
//Assuming bar needs to be called after foo has returned
//because of call signature in bar
foo().then(f => bar(f).then(b => baz(f, b)).then(log))
//using Promise.all in a block so p doesn't become global
//be carefull to ensure the call order lines up with
//the next then call you can also pass your previous resolved
// promises along in the array
{
let p; //temporary holder
Promise.all([p = foo(), p = p.then(bar)]).then(([f, b]) =>
Promise.all([f, b, baz(f, b)])).then(log)
}
//To have named promises you can use an object instead
//of an array if you use something like this
const resolver = o => {
var keys = Object.keys(o)
return Promise.all(keys.map(a => o[a])).then((a, i) =>
a.reduce((o, v, i) =>
(o[keys[i]] = v, o), {}))
}
, fooPromise = randWait(foo())
, barPromise = fooPromise.then(bar)
, bazPromise = resolver({
b: barPromise,
f: fooPromise
}).then(({
f, b
}) => baz(f, b))
, annoyingWait = randWait(bazPromise).then(a => 'did you really need to wait for me? ' + a)
, all = resolver({
annoyingWait, randWait, fooPromise, barPromise, bazPromise, nonPromise: 45, hiMom: delay(4000, 'hi')
})
//Using Await takes a lot of the power away from promises
//because, while it may not block the whole system, it will often
//unneccesarily pause parts of the code. Promises can give you a
//much more fine gain control over async events.
, justFooBazAndBar = resolver({
foo: fooPromise,
baz: bazPromise,
bar: barPromise
})
all.then(str).then(log)
justFooBazAndBar.then(log).then(o =>
//merge the object to be available to to the next promise
//use object.assign because promises results should always
//be immutable.
Object.assign({}, o, {
altBar: bar(o.foo + '2', o.bar + '2')
})).then(str).then(log)