我正在使用 Meteor,我需要做什么来等待从 API 调用返回承诺?


if (Meteor.isClient) {
  Template.hello.events({
    'click input': function () {
      //create a new customer
      Meteor.call('createCustomer', function (error, result) { 
        console.log("Error: " + error + "  Result: " + result); } );
    }
  });
}
if (Meteor.isServer) {
  Meteor.methods({
    createCustomer: function () {
      try {
      balanced.configure('MyBalancedPaymentsTestKey');
      var customer = Meteor._wrapAsync(balanced.marketplace.customers.create());
      var callCustomer = customer();
      var returnThis = console.log(JSON.stringify(callCustomer, false, 4));
      return returnThis;
    } catch (e) {
      console.log(e);
      var caughtFault = JSON.stringify(e, false, 4);
    }
    return caughtFault;
    }
  });
}

我只是使用了默认的hello世界,没有问候语。

<head>
  <title>testCase</title>
</head>
<body>
  {{> hello}}
</body>
<template name="hello">
  <h1>Hello World!</h1>
  <input type="button" value="Click" />
</template>

在客户端日志打印

Error: undefined Result: {}

在服务器端日志打印

[TypeError: Object [object Promise] has no method 'apply']

任何想法我可以等待那个承诺,而不是返回空白的结果?

我假设balanced.marketplace.customers.create返回承诺/a +承诺。这是一个具有.then(fulfillmentCallback, rejectionCallback)方法的对象——当操作成功时调用fulfillmentCallback,如果操作出错则调用rejectionCallback。下面是如何使用Futures同步获取promise的值:

var Future = Npm.require("fibers/future");
function extractFromPromise(promise) {
  var fut = new Future();
  promise.then(function (result) {
    fut["return"](result);
  }, function (error) {
    fut["throw"](error);
  });
  return fut.wait();
}

然后你可以正常调用balanced.marketplace.customers.create(没有_wrapAsync)来获得一个承诺,然后调用extractFromPromise来获得实际的结果值。如果有错误,那么extractFromPromise将抛出异常。

顺便说一下,if (Meteor.isServer)块中的代码仍然发送到客户端(即使客户端不运行它),所以你不想把你的API密钥在那里。您可以将代码放在server目录中,然后Meteor根本不会将其发送到客户机。

更新这一行

 var customer = Meteor._wrapAsync(balanced.marketplace.customer.create)();

另一种方法是使用期货。我在服务器端经常使用这个方法来等待结果返回给客户端。

下面是我用于登录的一个小示例:

Accounts.login(function (req, user) {
    var Future = Npm.require("fibers/future");
    var fut = new Future();
    HTTP.call("POST", globals.server + 'api/meteor-approvals/token',
        {
            timeout: 10000, followRedirects: true,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            params: {
                username: userName,
                password: req.password
            }},
        function (err, result) {
            if (err) {
                logger.error("Login error: " + err);
                fut.throw(err);
            }
            else {
                fut.return("Success");
            }
        }
    );
    return fut.wait();
}

最新更新