等待NodeJS中的异步方法 [英] Waiting for an Asynchronous method in NodeJS

查看:243
本文介绍了等待NodeJS中的异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看起来又高又低,只能找到如何编写异步函数,我已经理解了。

I've looked high and low, and can only find how to write async functions, which I already understand.

我要做的是运行一个触发事件[EventEmitter]中的异步方法,但是这样的简单事情似乎根本无法实现,因为我可以找到。

What I am trying to do is run an async method in a triggered event [EventEmitter], but such a simple thing seems to be just simply not possible as I can find.

请考虑以下内容......

Consider the following...

// Your basic async method..
function doSomething(callback) {
    var obj = { title: 'hello' };

    // Fire an event for event handlers to alter the object.
    // EvenEmitters are called synchronously
    eventobj.emit('alter_object', obj);

    callback(null, obj);
}

// when this event is fired, I want to manipulate the data
eventobj.on('alter_object', function(obj) {
    obj.title += " world!";

    // Calling this async function here means that our
    // event handler will return before our data is retrieved.
    somemodule.asyncFunction(callback(err, data) {
        obj.data = data;
    });
});

正如您在前几行中所看到的,事件处理程序将在对象的data属性之前完成添加。

As you can see in the last few lines, the event handler will finish before the object's data property is added.

我需要的是可以将异步功能转换为同步功能并在那里获得结果的东西。所以例如......

What I need is something where I can turn the async function into an sync function and get the results there and then. so for example...

obj.data = somemodule.asyncFunction();

我看过 wait.for 模块, async 模块,这些都不起作用。我甚至研究过 yield 方法,但它似乎尚未完全实现到V8引擎中。

I've looked at the wait.for module, the async module, and none of these will not work. I've even looked into the yield method, but it seems not yet fully implemented into the V8 engine.

我也尝试使用循环也等待数据填充,但这只会带来CPU过载问题。

I've also tried using a while loop too wait for data to populate, but this just brings with it the CPU overload issue.

有没有人经历过这个并找到了一个设计模式来解决这个问题?

Has anyone experienced this and found a design pattern to get around this?

推荐答案

似乎我想做什么是不可能的,这两个模型冲突。为了达到我想要的目的,我将模块封装成一个类似于数组的对象,其中包含一些事件方法,将它传递给模块的对象,该对象继承了 async-eventemitter class。

Seems what I wanted to do is just not possible and the two models conflict. To achieve what I wanted in the end, I encapsulated my modules into an array-like object with some event methods that will pass it on to the module's object, which inherited the async-eventemitter class.

所以,想想就好......

So, think of it like so...


  • 我的自定义应用程序模块可以继承async-eventemitter模块,因此它们具有 .on() .emit()等等方法。

  • 我创建了一个自定义数组项,这将允许我将事件传递给有问题的模块,该模块将异步工作。

  • My custom app modules may inherit the async-eventemitter module so they have the .on() and .emit(), etc. methods.
  • I create a customised array item, that will allow me to pass an event on to the module in question that will work asynchronously.

我创建的代码(这绝不是完整或完美的)......

The code I created (and this is by no means complete or perfect)...

// My private indexer for accessing the modules array (below) by name.
var module_dict = {};

// An array of my modules on my (express) app object
app.modules = [];

// Here I extended the array with easier ways to add and find modules.
// Haven't removed some code to trim down this.  Let me know if you want the code.
Object.defineProperty(app.modules, 'contains', { enumerable: false, ... });
Object.defineProperty(app.modules, 'find', { enumerable: false, ... });

// Allows us to add a hook/(async)event to a module, if it exists
Object.defineProperty(app.modules, 'on', { enumerable: false, configurable: false, value: function(modulename, action, func) {
    if (app.modules.contains(modulename)) {
        var modu = app.modules.find(modulename);
        if (modu.module && modu.module['on']) {
            // This will pass on the event to the module's object that
            // will have the async-eventemitter inherited
            modu.module.on(action, func);
        }
    }
} });
Object.defineProperty(app.modules, 'once', { enumerable: false, configurable: false, value: function(modulename, action, func) {
    if (app.modules.contains(modulename)) {
        var modu = app.modules.find(modulename);
        if (modu.on) {
            modu.on(action, func);
        }
    }
} });

这允许我通过简单地调用类似下面的内容将事件处理程序绑定到模块。 。 .on(module_name,event_name,callback)

This then allows me to bind an event handler to a module by simply calling something like the following... .on(module_name, event_name, callback)

app.modules.on('my_special_module_name', 'loaded', function(err, data, next) { 
    // ...async stuff, that then calls next to continue to the next event... 
    if (data.filename.endsWith('.jpg'))
        data.dimensions = { width: 100, height: 100 };

    next(err, data);
});

然后执行它我会做(快递)......

And then to execute it I would do something like (express)...

app.get('/foo', function(req, res, next) {
   var data = { 
       filename: 'bar.jpg'
   };

   // Now have event handlers alter/update our data
   // (eg, extend an object about a file with image data if that file is an image file).
   my_special_module.emit('loaded', data, function(err, data) {
       if (err) next(err);
       res.send(data);

       next();
   });
});

再一次,这只是我所做的一个例子,所以我可能错过了我的一些东西复制上面,但实际上它是我最终使用的设计,它的工作就像一个款待,我能够在推送到我的HTTP响应之前扩展对象的数据,而不必替换主[expressjs]对象的标准EventEmitter模型。

Again, this is just an example of what I did, so i've probably missed something in my copy above, but effectively it's the design I ended up using and it worked like a treat, and I was able to extend data on an object before being pushed out to my HTTP response, without having to replace the main [expressjs] object's standard EventEmitter model.

(例如,我添加了我们加载的文件的图像数据,我们是图像文件。如果有人想要代码,请告诉我,我是非常乐意分享我的所作所为)

(eg, I added image data for files that we're loaded that we're image files. If anyone wants the code, let me know, I am more than happy to share what I did)

这篇关于等待NodeJS中的异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆