Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我们如何在(Node.js 8.current)上的readline.on函数下使用promise_Javascript_Node.js_Ecmascript 6_Es6 Promise - Fatal编程技术网

Javascript 我们如何在(Node.js 8.current)上的readline.on函数下使用promise

Javascript 我们如何在(Node.js 8.current)上的readline.on函数下使用promise,javascript,node.js,ecmascript-6,es6-promise,Javascript,Node.js,Ecmascript 6,Es6 Promise,无法在readline.on函数下使用wait/async我不知道为什么它不等待结果返回?在等待函数下也使用了承诺,但在我返回承诺时没有用。请任何一位节点js、Es6方面的专家帮助我,这是我对所有开发人员的谦虚要求。请任何人帮我解决这个问题,并提前表示感谢 var readline = require('readline'); fs = require('fs'); redis = require('redis'); var redisClient = redis.createClient()

无法在readline.on函数下使用wait/async我不知道为什么它不等待结果返回?在等待函数下也使用了承诺,但在我返回承诺时没有用。请任何一位节点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

从上面的注释中复制:如果我理解正确,混乱是由回调和承诺代码混合造成的:每个异步回调开始按照
'line'
事件的顺序执行,直到第一个
等待
,然后根据另一个异步承诺,顺序是不可预测的。如果可以使用Node.js 11,请尝试使用异步迭代器API重写代码。参见示例和

我试着重写(修复了一些打字错误,比如最后一个输出块中的
result2
,而不是
result
)。这个代码有效吗

“严格使用”;
const readline=require('readline');
常数fs=要求('fs');
const redis=require('redis');
const redisClient=redis.createClient();
const filePath='./示例数据/whoodle_index_文件_0.psv';
异步函数getSampleData(){
const rl=readline.createInterface({
输入:fs.createReadStream(文件路径),
crlfDelay:无穷大
});
用于等待(rl的常量行){
常量obj={};
常量数据=行分割(“|”);
obj['name']=数据[0];
log(“执行过程的第一行”);
const result=await GetDatafromRedusingKey(obj['name']);
console.log('result'+result);
log(“执行过程的第二行”);
log('希望将此结果用于其他一些函数');
常量obj2={};
obj2['name']=数据[3];
log(“执行过程的第三行”);
const result2=await GetDatafromRedusingKey(obj2['name']);
console.log('result2'+result2);
log(“执行过程的第四行”);
log('希望将此结果用于其他一些函数');
}
}
getSampleData();
函数GetDataFromRedusingKey(名称){
返回新承诺(功能(解决、拒绝){
redisClient.get(名称、函数(错误、结果){
console.log('result--------------------'+result);
如果(错误){
拒绝(错误);
}否则{
决心(结果);
}
});
});
}

值得一提的是,这里有一个预期行为的模型,使用一系列承诺作为“等待条件”:

//实体模型rl
const EventEmitter=require('events');
const rl=新的EventEmitter();
//模拟getDataFromRedis的东西:这给出了一个在1s后实现的承诺
函数doSomething(){
返回新承诺((解决、拒绝)=>{
设置超时(解析,1000);
});
}
//“等待条件”变量
常数储物柜=[];
rl.on('line',async()=>{
//将代码包装在承诺中,作为等待条件添加
储物柜。推送(新承诺(异步(解析、拒绝)=>{
//现在,我们等待所有以前注册的条件都正常后再继续
等待承诺。所有(储物柜);
//现在我们用Redis做代码
console.log('x1');
常数r1=等待剂量测量();
console.log('x2');
常数r2=等待doSomething();
//最后,我们解决了当前释放以下进程锁的承诺
解决();
}));
});
//启动流程:模拟rl的行为:连续触发多个事件
for(设i=0;i<10;i++){
rl.emit('line');
}
然而,这种架构真的很奇怪:为什么需要“顺序化”流程?我的意思是:即使一切都是并行的,你最终还是可以检索到有序的数据,假设你为它编写代码的话

要解释引擎盖下发生的情况:

  • rl
    触发
    “行”
  • JS将侦听器调用到该事件,作为一种良好的基于单线程事件的语言,它执行侦听器的代码,直到到达第一个
    wait
    ,然后检查是否有另一段代码请求处理
  • 同时,
    rl
    触发了另一个(或一些其他的)
    “line”
    事件,因此这是“另一段请求处理的代码”,因此JS执行它,直到它到达一个
    等待
  • 同样,在
    wait
    上,它将检查要处理的事件队列,现在您可以猜测如果
    rl
    触发事件的速度快于内部代码的第一个
    wait
    :在解释器时间内,所有
    rl
    的事件将排在第一位,所有的内部代码都必须等待,然后才能准备好处理它们的最后一段代码

然而,当JS再次开始处理您的内部代码时(即,在Redis的异步函数解析之后,以及在处理了之前注册的任何事件之后),它会将其加载到其作用域中,因此您不必担心数据的混合。唯一令人担忧的是检索数据的顺序:如果需要,则必须明确地考虑它,例如使用一组承诺(因为数组中的允诺对象显然是按顺序排列的,不管这些承诺的执行顺序)。

您忘记了<代码>等待<代码> <代码>承诺< /代码>。如果我创建了一个具有某个名称的函数,并将其粘贴到新的承诺代码中,然后使用Wait调用该函数,那么您也应该
拒绝
错误,而不是
解决
,同样没有用,我的意思是Wait函数没有首先执行。如果您需要调试帮助,请发布该代码。刚才更新的问题,请再次检查您应该“返回”promiseI正在使用节点8.9,它在8.9上为Wait(rl的常量行)给出错误{^^^^^语法错误:意外保留字,因此它仅在节点11.4上工作
// 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', async () => {
  // 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');
}