【问题标题】:Meteor wrapAsync or bindEnvironment without standard callback signature没有标准回调签名的 Meteor wrapAsync 或 bindEnvironment
【发布时间】:2018-07-01 15:27:30
【问题描述】:

我试图在这个 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() 在回调设置之前返回 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()

谢谢!

【问题讨论】:

  • 使用future 应该可以。我
  • 谢谢 - 你能详细说明一下吗?我对`future`一点也不熟悉。看着这个包npmjs.com/package/fibers,但不知道如何修改我上面的代码。 ====OR==== 从demoFunction() 返回一个Promise 也是一个选项吗?我比较熟悉使用async/await
  • 对不起,我在奔跑中的简短回答,我在家时会尽量给你一个更详细的答案。
  • 实际上,从demoFunction 返回一个Promise,然后rejecting/resolving 它在bindEnvironment 函数中起作用了......我没有意识到bindEnvironment 会解决外部Promise ......虽然现在它以它的名字继承外部环境是有道理的:) =====>>>> 如果可能的话,我仍然希望看到一个Future 解决方案,它可以通过创建来启用任意数量的异步调用与demoFunction() 光纤同步,因为我以后可能会需要它。

标签: meteor node-fibers


【解决方案1】:

您可以使用fibers/future (node-fibers) 包中的Future,它只是与this async/await implementationthis promise implementation 不同的光纤抽象层, 也。 (注意,直接使用光纤is not recommended)。

通用未来模式

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

但是,如果您想知道如何使用 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();

}

【讨论】:

    猜你喜欢
    • 2015-01-03
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    相关资源
    最近更新 更多