【问题标题】:How to yield value multiple times from function?如何从函数中多次产生价值?
【发布时间】:2021-07-18 11:59:33
【问题描述】:

所以我正在做的是,我有 2 个文件,一个包含将生成令牌的脚本,第二个文件处理该令牌。

问题在于,记录令牌的第二个脚本只会记录收到的第一个令牌。

这就是我处理令牌的方式:

const first_file = require("./first_file.js");
first_file.first_file().then((res) => {
    console.log(res);
});

显然这行不通,因为它没有使用更新的值进行更新。

first_file = async () => {
    return new Promise(async (resolve, reject) => {
        //Generating the token
        (async () => {
            while (true) {
                console.log("Resolving...");
                resolve(token);
                await sleep(5000);
                resolved_token = token;
            }
        })();
    });
};

module.exports = { first_file };

我在这里做的是,我尝试做一个while..loop,以便我继续解析令牌。但它没有,有没有办法可以直接导出变量,这样任务会更容易?

【问题讨论】:

  • 抱歉这个不好的问题只是不知道如何解释我想要什么
  • token 是什么,你是从某个地方获取的吗?
  • 您不需要为while 循环包装内联async 函数以使用await 关键字。也用于返回 Promise 对象
  • Never pass an async function as the executor to new Promise!而那个 IIFE 似乎也毫无意义。

标签: javascript promise generator


【解决方案1】:

如果我正确理解你的问题,你想多次解决承诺,这与模块无关......

但是你对 JavaScript 中的 Promise 的理解有些不对...
你不能两次解决一个承诺。

发电机

但是您可以从函数中生成新值,这种类型的函数也称为generator,其中函数可以重新进入其上下文(类似于async/await)并使用yield 关键字产生结果。

通常在for..of 循环中使用生成器。它有 next() 方法从生成器中产生下一个值...

让我们看一个例子:

const delay = ms => new Promise(res => setTimeout(res.bind(null, ms), ms));

async function* generator() {
    yield 'yield result from generator!'
    for (let ms = 100; ms <= 300; ms += 100) {
        yield 'delay: ' + await delay(ms) + ' ms';
    }
    yield delay(1000).then(() => 'you can also yield promise!');
}

async function main() {
    const gen = generator();
    console.log('1st', (await gen.next()).value);
    for await (const ms of gen) {
        console.log(ms)
    }
}

main()

注意*在函数后面,这样我们就知道这个函数是一个生成器,加上async关键字这是Async Generator

生成器非常有用。比如:按需生成值,像管道一样传递数据!可以从函数中返回无穷无尽的值等等......

回调

这种在节点中大量使用的老派方法,您将回调函数作为参数传递。

例子:

const delay = ms => new Promise(res => setTimeout(res.bind(null, ms), ms));

async function callback(fn) {
    fn('yield result from callback!');
    for (let ms = 100; ms <= 300; ms += 100) {
        fn('delay: ' + await delay(ms) + ' ms');
    }
    await delay(1000);
    fn('yield asynchronously!');
}

callback(value => console.log(value));

这种方法会产生各种棘手的问题,例如:创建函数范围、控制流灾难、没有break 关键字等... 我不推荐这种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多