javascript 链异步函数

z18hc3ub  于 2023-04-28  发布在  Java
关注(0)|答案(5)|浏览(136)

在一个async函数中,我可以像这样获得一个异步值:
const foo = await myAsyncFunction()
如果我想对结果调用一个方法,使用一个同步函数,我会执行类似于myAsyncFunction().somethingElse()的操作
是否可以用异步函数来链接调用,或者你必须为每个结果分配一个新的变量?

mctunoxg

mctunoxg1#

我更喜欢将第一个结果赋给一个中间变量,我个人觉得它更易读。
如果你愿意,你可以在表达式中等待,而不需要赋值。你所要做的就是使用括号。看我的例子:

const foo = await (await myAsyncFunction()).somethingElseAsync()

或者,如果您想对结果调用sync方法:

const foo = (await myAsyncFunction()).somethingElseSync()
qjp7pelc

qjp7pelc2#

我很惊讶,它没有被提到,但可能最容易理解的方式来实现这一点,而不需要额外的变量是使用.then链,await在最后:

await myAsyncFunction()
  .then(res => res.somethingElse())

请记住,await与promises一起工作,但不会取代它们!

qvtsj1bj

qvtsj1bj3#

您可以试试这个套餐。

// Instead of thens
fetch(url)
  .then(res => res.json())
  .then(json => json.foo.bar)
  .then(value => console.log(value))

// Instead of awaits
const res = await fetch(url)
const json = await res.json()
const value = json.foo.bar
console.log(value)

// With prochain
const value = await wrap(fetch(url)).json().foo.bar
console.log(value)
bmvo0sr5

bmvo0sr54#

This answer(Tamas Hegedus)用括号括住await表达式绝对是使用vanilla JavaScript的方法。
或者,如果你正在寻找常用的JS方法,并且不介意使用第三方模块,你可以在npm上使用async-af。使用它,你可以像这样链接异步方法:

const promises = [1, 2, 3].map(n => Promise.resolve(n));

AsyncAF(promises).map(n => n * 2).filter(n => n !== 4).forEach(n => console.log(n));
// logs 2 then 6
<script src="https://unpkg.com/async-af@7.0.11/index.js"></script>
4ktjp1zp

4ktjp1zp5#

如果你不想每次都调用then(d => d.method()),你可以用一个小的helper函数来 Package 你的异步调用:

const buy = {
  cart: [],
  apple: async function() {
    setTimeout(() => {
      this.cart.push('apple');
      console.log(this.cart);
    }, 1000);
    return this;
  }
};

function chain(object, ...asyncMethods) {
  const methods = [...asyncMethods];

  methods.reduce((acc, curr) => {
    // if object is not a promise (first iteration), call the method 
    if (!acc.then) {
      const promise = curr.call(acc);
      return promise;
    } else {
      // if object is a promise, resolve it, then call the method
      return acc.then((d) => curr.call(d));
    }
  }, object);
}

chain(buy, buy.apple, buy.apple, buy.apple);

// ['apple']
// ['apple', 'apple']
// ['apple', 'apple', 'apple']

但是,如果必须向方法传递参数,这将不起作用。在这种情况下,您可以将函数调用作为像{buy: "orange"}这样的对象传递,然后在帮助程序中解构它们。

相关问题