没有标准回调签名的 Meteor wrapAsync 或 bindEnvironment

Meteor wrapAsync or bindEnvironment without standard callback signature

我试图在这个 npm 包中调用 createTableIfNotExists,并在服务器端的 Meteor 中同步调用。 https://www.npmjs.com/package/azure-storage

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

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

2) 我调用 'bindEnvironment' 如下。注意带有 3 个参数的回调。这行得通,但现在我想提取 return value,回到原来的方法(即原来的纤维)。

请注意,在 createTableService 之外简单地定义 'addResult' 是行不通的,因为 bindEnvironment 内的回调相对于外部代码异步运行...即demoFunction() return 秒回调设置前 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 并且仍然 return addResult 返回到调用 [=42 的函数=] demoFunction()?

谢谢!

您可以使用 fibers/future 中的 Futurenode-fibers) package, which is just a different abstraction layer of fibers as this async/await implementation or this promise implementation, 也。 (注意,直接使用光纤is not recommended)。

通用未来模式

正如您已经指出的,您也可以使用 async/await 或使用 promises 来解决这个问题。

但是,如果您想知道如何使用 Future 实例,您可以关注 this popular pattern,我在我的许多应用程序中都使用了它。

Meteor.bindEnvironment

的未来格局

bindEnvironment 包含到此模式中,并稍微重构代码,如下所示:

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();
    }
});

应用于代码示例

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

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();

}