【问题标题】:Which one of my function declaration is better? generator or async/await?我的哪个函数声明更好?生成器还是异步/等待?
【发布时间】:2020-01-10 09:05:02
【问题描述】:

我想写一个函数,但不知道哪个更好:

function* call() {
    try {
        const a = yield api(1);
        const b = yield api(2);
        const c = yield api(3);
        const d = yield api(4);

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}

异步/等待

async function call() {
    try {
        const a = await api(1);
        const b = await api(2);
        const c = await api(3);
        const d = await api(4);

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}

两个都很好用,不知道哪一个更好,也不知道有什么区别。

【问题讨论】:

  • thecodebarbarian.com/… 当你可以使用await 时使用yield 似乎很奇怪,我认为。如果api 只返回 Promises,你代码的读者会想知道生成器的目的是什么
  • 他们返回的不是不同的东西吗?我认为生成器只会在第一次调用时返回部分结果。
  • 它是如何工作的?
  • @D_N 生成器可用于实现 async/await(例如,如果 async/await 不可用,如 2015 年),如果您使用蹦床调用函数(例如通过 co模块)。然而,由于我们现在有 async/await,我认为它是一种反模式(虽然在 2015 年还可以,但我更喜欢回调而不是生成器——这是我从未使用过 Koa 框架的原因之一)

标签: javascript ecmascript-6 async-await generator


【解决方案1】:

不,它们并不完全相同,区别如下:

  1. call() 调用会返回一个生成器 function* 的迭代器对象,而 async 函数会返回一个封装在 Promise 中的数组。

  2. 1234563但在 async 版本中,您将在 Promise 包装数组中取回从 api() 调用返回的值。
  3. 当您遍历迭代器时,yield 语句也会返回值,但在 async 函数中,await 将等待由 api() 调用返回的 Promise 然后解析继续下一个await,否则如果该值不是来自api() 调用的Promise,它会将其转换为已解决的Promise,并且await 表达式的值将成为已解决的Promise 的值。

这三点可以用 sn-p 来说明。

  1. 生成器函数:

function* call() {
    try {
        const a = yield 1;
        const b = yield 2;
        const c = yield 3;
        const d = yield 4;

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}
const itr = call();
//next() is not invoked with any params so the variables a, b, c, d will be undefiend
console.log(itr.next().value); 
console.log(itr.next().value);
console.log(itr.next().value);
console.log(itr.next().value);
console.log(itr.next().value); 
  1. 异步函数:

async function call() {
    try {
        const a = await 1;
        const b = await 2;
        const c = await 3;
        const d = await 4;

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}
//call() will return a Promise
call().then(data => console.log(data));

【讨论】:

  • 大概 OP 正在使用诸如co 之类的蹦床库来调用生成器。生成器(或其他语言的协同程序)和蹦床可用于将 async/await 作为设计模式而不是语言特性来实现。
【解决方案2】:

顺便说一句,这称为生成器函数。

 function* call()

async/await 和生成器之间最重要的区别是 一直到 Node.js 都原生支持生成器 4.x,而 async/await 需要 Node.js >= 7.6.0。然而,鉴于 Node.js 4.x 已经到了生命周期的尽头,而 Node.js 6.x 将 在 2019 年 4 月达到使用寿命,这种差异正在迅速成为 无关的。 来源:https://thecodebarbarian.com/the-difference-between-async-await-and-generators

Aysnc/Await 提供了一种更简洁的方法来处理并发。但是生成器函数提供了更大的灵活性。

选择取决于您想要实现的目标,但在大多数情况下,如果您使用的是现代版本的 NodeJs,则特别使用 async/await 是有意义的,但是

【讨论】:

    猜你喜欢
    • 2017-12-06
    • 1970-01-01
    • 2019-11-27
    • 2021-07-04
    • 2019-06-16
    • 2021-06-05
    • 1970-01-01
    • 2019-11-29
    • 2023-03-10
    相关资源
    最近更新 更多