javascript - 我们如何在 readline.on 函数下使用 promise on (Node.js 8. Currently)

标签 javascript node.js ecmascript-6 es6-promise

无法在 readline.on 函数下使用 await/async 我不知道为什么不等到结果返回?还在 await 函数下使用了 promise,但是当我返回 promise 时也没有用,也没有用。任何精通node js,Es6的人都可以帮助我,这是我对所有开发人员的卑微请求。任何人都可以帮我解决这个问题,在此先感谢。

var readline = require('readline');
fs = require('fs');
redis = require('redis');

var redisClient = redis.createClient();

var filePath = './sample-data/whoodle_index_file_0.psv';

async function getSampleData() {
    let rl = readline.createInterface({
        input: fs.createReadStream(filePath),
        crlfDelay: Infinity
    });

    rl.on('line', async (line) => {

        let obj = {};
        let data = line.split('|');
        obj['name'] = data[0];

        console.log('first line of execution process');

        let result = await getDataFromRedisUsingKey(obj['name']);
        console.log('result' + result);
        console.log('secound line of execution process');
        console.log('want to use this results in to some other functions');

        let obj2 = {};
        obj2['name'] = data[3];

        console.log('third line of execution process');

        let result2 = await getDataFromRedisUsingKey(obj2['name']);
        console.log('result' + result);
        console.log('fourth line of execution process');
        console.log('want to use this results in to some other functions');

    });

}

getSampleData();

async function getDataFromRedisUsingKey(name) {
    return new Promise(function (resolve, reject) {
        redisClient.get(name, function (err, result) {
            console.log("result----------------------" + result);
            if (err) {
                reject();
            } else {
                resolve(result);
            }
        });
    });
}

Showing result like this on console 

first line of execution process
first line of execution process
result----------------------null
result----------------------null
resultnull
secound line of execution process
want to use this results in to some other functions
third line of execution process
resultnull
secound line of execution process
want to use this results in to some other functions
third line of execution process
result----------------------null
result----------------------null
result2null
fourth line of execution process
want to use this results in to some other functions
result2null
fourth line of execution process
want to use this results in to some other functions

But im expecting like this

first line of execution process
result----------------------null
resultnull
secound line of execution process
want to use this results in to some other functions
third line of execution process
result----------------------null
result2null
fourth line of execution process
want to use this results in to some other functions
first line of execution process
result----------------------null
resultnull
secound line of execution process
want to use this results in to some other functions
third line of execution process
result----------------------null
result2null
fourth line of execution process
want to use this results in to some other functions

最佳答案

对于它的值(value),这是预期行为的模型,使用一系列 promise 作为“等待条件”:

// mock-up rl
const EventEmitter = require('events');
const rl = new EventEmitter();

// mock-up the getDataFromRedis thing: this gives a Promise that is fulfilled after 1s
function doSomething() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000);
  });
}

// "waiting condition" variable
const lockers = [];

rl.on('line', () => {
  // wrap the code in a Promise that we add as a waiting condition
  lockers.push(new Promise(async (resolve, reject) => {
    // now we wait for all previously registered conditions to be OK before going on
    await Promise.all(lockers);
    // now we do the code with Redis
    console.log('x1');
    const r1 = await doSomething();
    console.log('x2');
    const r2 = await doSomething();
    // finally we resolve the current Promise to release lock on following processes
    resolve();
  }));
});

// start the process: mock-up rl's behavior: fire several events in a row
for (let i = 0; i < 10; i++) {
    rl.emit('line');
}

但是,这个架构真的很奇怪:为什么需要对流程进行“顺序化”?我的意思是:即使一切都并行,你仍然可以最终检索有序数据,假设你为它编写代码!

解释幕后发生的事情:

  • rl 触发 "line"
  • JS 召唤监听器到那个事件,作为一个很好的单线程基于事件的语言,它执行监听器的代码直到它到达第一个 await,然后它检查是否有另一段代码请求处理
  • 与此同时,rl 触发了另一个(或其他)"line" 事件,因此这是“另一段请求处理的代码”,因此 JS 执行它,直到它到达 await 或类似的
  • 同样,在 await 上,它会检查要处理的事件队列,现在你猜如果 rl 触发事件的速度比内部代码的第一个 await:rl 的所有事件都将在解释器时间排在第一位,并且您的所有内部代码都必须等待,然后才能准备好处理它们的最后一部分代码

然而,当 JS 再次开始处理您的内部代码时(即在 Redis 的异步函数解析之后以及在处理任何先前注册的事件之后),它会加载它及其范围,因此您不必担心混合您的代码数据。唯一令人担忧的一点是检索该数据的顺序:如果需要,那么您必须明确考虑它,例如使用一个 promise 数组(因为数组中的 Promise 对象显然保持顺序,无论这些执行顺序如何 promise )。

关于javascript - 我们如何在 readline.on 函数下使用 promise on (Node.js 8. Currently),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54417303/

相关文章:

javascript - iOS 检测网页上安装的应用程序

javascript - 动态 react 设置状态属性及其值

node.js - MapReduce 确定分类账中的信用余额

node.js - 如何使用 VSCode 通过 Firestore 触发器调试 Google Cloud Functions?

php - 什么设置(ab)使用node.js作为超快速轮询和ajax服务器来更新数据库(类似于Google Spreadsheet方法)

Javascript |最小和最大方法到一种 DRY 方法

javascript - 基于配置的Webpack多重 bundle

javascript - 为面添加厚度

javascript - 为什么我必须将部分条件放在括号中以防止语法错误?

javascript - JavaScript 问题 - 图像居中