没有标准回调签名的 Meteor wrapAsync 或 bindEnvironment [英] Meteor wrapAsync or bindEnvironment without standard callback signature

查看:75
本文介绍了没有标准回调签名的 Meteor wrapAsync 或 bindEnvironment的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在此 npm 包中调用 createTableIfNotExists,并在服务器端 Meteor 中同步调用.https://www.npmjs.com/package/azure-storage

I'm trying to call createTableIfNotExists in this npm package, and do so synchronously in Meteor, server-side. https://www.npmjs.com/package/azure-storage

然而,回调签名的类型是function(error, result, response),而不是传统的function(error,result).

However, the callback signature is of type function(error, result, response) instead of the traditional function(error,result).

1) 因此,我不能使用 Meteor.wrapAsync 而必须使用 Meteor.bindEnvironment

1) Because of that, I cannot use Meteor.wrapAsync and instead have to use Meteor.bindEnvironment

2) 我将bindEnvironment"称为如下.注意带有 3 个参数的回调.这有效,但现在我想提取返回值,回到原始方法(即原始光纤).

2) I call 'bindEnvironment' as below. Note the callback with 3 arguments. This works, but now I would like to extract the return value, back to the original method (i.e. the original fiber).

请注意,在 createTableService 之外简单地定义addResult"是行不通的,因为 bindEnvironment 内的回调相对于外部代码异步运行......即demoFunction() 在回调设置 addResult 之前返回.

Note that simply defining 'addResult' outside the createTableService does not work because the callback inside bindEnvironment runs asynchrounously relative to the outside code...i.e. demoFunction() returns before the callback sets addResult.

var demoFunction = function(){
    var addResult = null;
    var tableService = azure.createTableService(acctName, acctKey);
                    tableService.createTableIfNotExists(asTableName, Meteor.bindEnvironment(function(error,result,response){
                        if (error) {
                            throw new Meteor.Error(500, "table create error - " + asTableName + ": "+ error);
                        }
                        console.log(result);
                        if(result){
                            addResult = /*call to meteor method*/ 
                            return addResult;
                        }                   
                    }));

    return addResult; //this is what I would like to do, but will always be null, as written.

}

如何调用 createTableIfNotExists 并仍然返回 addResult 回到调用的函数 demoFunction()?

How can I call createTableIfNotExists and still return addResult back to the function that called demoFunction()?

谢谢!

推荐答案

您可以使用 fibers/future (node-fibers) 包,它只是一个与 这个异步/等待实现这个承诺实现是,也.(请注意,不推荐直接使用光纤).

You can use the Future from the fibers/future (node-fibers) package, which is just a different abstraction layer of fibers as this async/await implementation or this promise implementation are, too. (Note, that using a fiber directly is not recommended).

正如您已经指出的,您也可以使用 async/await 或使用 promise 来解决此问题.

As you already pointed out, you can solve this issue also using async/await or using promises.

但是,如果您想知道如何使用 Future 实例,您可以关注 这种流行的模式,我在我的许多应用程序中都使用了它.

However, if you want to know how to use a Future instance, you can follow this popular pattern, which I make use of in many of my applications.

bindEnvironment 包含到这个模式中,并稍微重组一下代码,它看起来像这样:

Including the bindEnvironment into this pattern, and restructuring the code a bit, it looks like the following:

import Future from 'fibers/future';

Meteor.methods({
    myMeteorMethod: function() {
        // load Future
        const myFuture = new Future();

        // create bound callback, that uses the future
        const boundCallback = Meteor.bindEnvironment(function (error,results){
            if(error){
              myFuture.throw(error);
            }else{
              myFuture.return(results);
            }
        });

        // call the function and pass bound callback
        SomeAsynchronousFunction("foo", boundCallback);

        return myFuture.wait();
    }
});

应用于代码示例

将模式的这种修改应用到您的代码中,可能会产生类似于以下代码的结果.请注意,我将回调与在函数内部创建分开,只是因为可读性.您当然可以像往常一样在函数头中创建它.

Applied to code example

Applying this modification of the pattern to your code, it could result in something like the code below. Note, that I separated the callback from being created inside the function simply because of readability. You can of course just create it inside the function head, as you typically do.

import Future from 'fibers/future';

var demoFunction = function(){
    // load Future
    const myFuture = new Future();

    // create bound callback, that uses the future
    const boundCallback = Meteor.bindEnvironment(function (error, result, response) {
        if (error) {
            myFuture.throw(new Meteor.Error(500, "table create error - " + asTableName + ": "+ error));
        }

        // do whatever you need to do here
        // with result and response...

        if (result) {
            myFuture.return(result);
        }                   
    });

    var tableService = azure.createTableService(acctName, acctKey);

    // pass the bound callback here
    tableService.createTableIfNotExists(asTableName, boundCallback);

    return myFuture.wait();

}

这篇关于没有标准回调签名的 Meteor wrapAsync 或 bindEnvironment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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