Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.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 如何从事件发射器调用的异步函数返回同步函数的值?_Javascript_Node.js_Asynchronous_Events_Async Await - Fatal编程技术网

Javascript 如何从事件发射器调用的异步函数返回同步函数的值?

Javascript 如何从事件发射器调用的异步函数返回同步函数的值?,javascript,node.js,asynchronous,events,async-await,Javascript,Node.js,Asynchronous,Events,Async Await,我有同步工作逻辑,我想把它转换成异步事件驱动代码 如何使async foo返回事件链末尾回调(done()| | fail())的预期值 就像让这个过于简单的例子起作用一样 async function foo(param){ eventEmitter.emit('first-event', param); } eventEmitter.on('first-event', /*Do something*/); . . . eventEmitter.on('last-event', (pay

我有同步工作逻辑,我想把它转换成异步事件驱动代码

如何使async foo返回事件链末尾回调(done()| | fail())的预期值

就像让这个过于简单的例子起作用一样

async function foo(param){
  eventEmitter.emit('first-event', param);
}

eventEmitter.on('first-event', /*Do something*/);
.
.
.
eventEmitter.on('last-event', (payload) => {
  try{
   /*If no error*/
   eventEmitter.emit('done', payload);
  }catch{
   /*If error*/
   eventEmitter.emit('fail', error);
  }
});

function done(payload){
  return ({payload:payload});
}

function fail(error){
  return ({fail:error});
}

eventEmitter.on('done', payload => done(payload) );

eventEmitter.on('error', error => fail(error) );


如果任何人有关于它的信息,感谢分享它和您的时间,对任何错误表示抱歉。

如果必须这样做,承诺构造函数将工作:

let p = {};
async function foo(param) {
  eventEmitter.emit('first-event', param);
  return await new Promise((res, rej) => (p.res = res) && (p.rej = rej));
}
//...
eventEmitter.on('done', payload => done(payload) && p.res());

eventEmitter.on('error', error => fail(error) && p.rej());


在大量阅读以下评论和链接后:

@Bergi 
@TheMaster
@Thomas
我想我已经找到了最好的解决办法,我希望我没有错,如果我错了,我希望不要要求回应的人带着解决问题的意图这样做,而不是仅仅指出错误或不喜欢的东西

“请让我看看代码!”而不是;)

这是拆分字符串的最愚蠢的方法的一个示例 使用eventEmitter、async await和此方法,一切正常

let event = new(require('events').EventEmitter);

async function split(string) {

  let holder = {};
  let promise = async() => {
    return await (holder.payload || holder.error) ? holder : null;
  }

  event.on('done', data => done(data));

  function done(data) {
    try {
      console.log('Done emitted');
      console.log(`Param: ${data}`);
      holder.payload = data;
    } catch(error) {
      console.log(error);
    }
  }

  event.on('error', error => fail(error));

  function fail(error) {
    try {
      console.log('Fail emitted');
      console.log(`Param: ${error}`);
      holder.error = error;
    } catch(error) {
      console.log(error);
    }
  }

  event.on('split', async(string) => {
    try {
      console.log('Split emitted');
      console.log(`Param : ${string}`);
      const data = string.split(' ');
      event.emit('done', data);
    } catch(error) {
      console.log(error);
      event.emit('error', error);
    }
  });

  try {
    event.emit('split', string);
    return({ payload: await promise().then(data => { return data.payload }) });
  } catch(error) {
    console.log(error);
  }

}

console.clear()
console.log(
  split('Hello world').then(data => {
    console.log('Split done!');
    console.log(data);
  })
);

因此,在这一点上,var“holder”和函数“promise” 位于功能“split”的勺内,所有控制台输出为:

Split emitted
Param : Hello world
Done emitted
Param: Hello,world
Promise { <pending> }
Split done!
{ payload: [ 'Hello', 'world' ] }
Split发射
帕拉姆:你好,世界
完成发射
帕拉姆:你好,世界
承诺{}
分手吧!
{payload:['Hello','world']}
整个要点是要说明有n个异步事件、回调和承诺是可能的 并且能够在n个阶段或事件的过程之后返回一个值


感谢您的时间和其他评论,对于出现的错误,我深表歉意。

“我想将其转换为异步事件驱动代码。”-为什么?您可以发布您的工作同步逻辑,并告诉我们它如何不再满足您的要求吗?一般来说,只需(使用
'error'
,而不是
'fail'
)使用构造函数functions@Thomas嗯,没有?@Bergi“你能发布你的工作同步逻辑,并告诉我们它如何不再满足你的要求?”不是关于需求,而是关于将其转换为发出的事件不,不要这样做。不要导出
拒绝
解析
函数,只需将
on()
调用移到
新承诺
执行器中即可。@Bergi有任何反对导出的具体原因吗?如果我把它放进去,它可能看起来像是回调地狱,如果代码增长,不创建,因为可变的
p
,全局范围内的变量更少,更好地控制谁可以解决承诺(无法访问
p
),一般来说,代码更简单,错误处理也更好。事实上,我甚至认为,如果多次调用
foo()
,您的代码将无法运行,因此您的代码已被破坏,但考虑到OP设置
eventEmitter
的方式,它可能无论如何都无法运行。同样,我们使用承诺来避免回调地狱:如果代码增长,它将在
新承诺
之外增长,在
等待
之后-这就是练习的全部要点。“我想我找到了最好的解决方案”-不,你没有。除了人为的承诺之外,这段代码没有任何异步性。它之所以有效,是因为所有事件都是同步发出的。通过
async function split(string){return string.split(“”);}
或者仅仅是
function split(string){return Promise.resolve(string.split(“”));}
@Bergi是一个非常有教育意义的答案,它包含了代码,但是其中的事件在哪里呢?关键是使用n个事件对变量或参数执行n项操作,并从上一个事件返回值“如何从事件发射器调用的异步函数中从同步函数返回值?”其中没有事件,这就是关键所在。你不应该使用它们,它们只会使你的代码更复杂。同步发出的事件甚至不会使任何东西异步。