【问题标题】:I'm using Meteor, what do I need to do to wait for a promise to be returned from an API call?我正在使用 Meteor,我需要做什么才能等待从 API 调用返回的承诺?
【发布时间】:2014-05-21 02:33:09
【问题描述】:
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 world,没有问候线。

<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']

知道如何等待该承诺而不是返回空白结果吗?

【问题讨论】:

  • 更新此行var customer = Meteor._wrapAsync(balanced.marketplace.customer.create)();

标签: meteor balanced-payments


【解决方案1】:

我假设 balanced.marketplace.customers.create 返回一个 Promises/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)来获得一个promise,然后在那个promise上调用extractFromPromise来获得实际的结果值。如果有错误,那么extractFromPromise 会抛出异常。

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

【讨论】:

  • 哇,好极了,你是我的英雄。你不知道我花了多少时间试图解决这个问题。谢谢!我放在 JSFiddle.net 上,以便您可以更好地查看代码。 jsfiddle.net/zhvTq/1 然后当然要使用我运行的 API 密钥访问 settings.json 文件 mrt --settings settings.json
【解决方案2】:

更新这一行

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

【讨论】:

  • 当我改变那条线时,我在客户端和服务器端都没有得到任何东西。我什至在方法中的每个步骤之间添加了控制台日志,并且在服务器或客户端的控制台上没有打印任何内容...
  • 显示代码:balanced.marketplace.customers.createDefine
  • 我正在使用包balanced-payments-production,它包装了balanced-official node包,这样我就可以在我的代码中的任何地方调用balanced。看到可以看节点包npmjs.org/package/balanced-official
【解决方案3】:

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

这是我用于登录的一个小例子:

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

【讨论】:

  • 好的,我之前试过用future。我不确定如何编写我的函数。这是我重写它的方法,但我知道这是不对的。 createCustomerFuture: function () { var Future = Npm.require("fibers/future"); var fut = new Future(); function runThisHere(function (err, result) { balanced.configure('TESTKEYHERE'); balanced.marketplace.customer.create(); }); return fut.wait(); }
  • 我稍微更改了代码,现在我得到的结果与赵友发布的其他解决方案相同。 createCustomerFuture: function () { var Future = Npm.require("fibers/future"); var fut = new Future(); function runThisHere(err, result) { balanced.configure('TESTKEYHERE'); var customer = balanced.marketplace.customer.create(); console.log(customer); }; return fut.wait(); }
  • 很难阅读(不知道为什么 stackoverflow 不允许 cmets w/code 但这是一个单独的问题),但我明白了要点。假设您想将客户返回给调用函数,您需要在 runThisHere 函数中放置一个 fut.return(customer)。 HTH。
  • 我添加了,但我仍然没有得到任何回应。我现在有 _wrapAsync、futures 和 Async.wrap 函数。我没有收到 _wrapAsync 的回应,也没有收到期货的回应。我从 Async.wrap 函数中得到一个Error: undefined Result: {} 。我想知道这里是否存在异步编码之外的问题。也许我正在使用 API 调用来平衡错误(尽管我正在关注他们的文档docs.balancedpayments.com/1.1/api/customers/#create-a-customer)。任何其他想法都会很棒。
  • 我对此并不熟悉,但查看这些文档似乎表明您必须对您的 balancepayments 服务器进行 HTTP POST,不是吗?如果是这种情况,您可以使用我上面的代码执行 POST 并插入您自己的标头、参数和数据值。
猜你喜欢
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
相关资源
最近更新 更多