Flutter - 等待 JavaScript Promise (promiseToFuture)

Flutter - waiting for JavaScript Promise (promiseToFuture)

我正在尝试为我的 Flutter 应用程序集成 Braintree 支付。我有一个插件可以处理 iOS/Android 并且正在为 web 编写自定义实现。

我认为这是一个相当简单的解决方案,我在 UI (GitHub tutorial) 中使用 Braintree Javascript SDK/Drop 来使用 HTML。这部分我开始工作,但是为了正确处理这些付款,我需要检索 JavaScript 函数的响应 - 特别是付款随机数的字符串。

为此,我使用了一些通道方法和飞镖魔法来调用此 javascript 函数

async function payment(auth) {
 braintree.dropin.create({
   authorization: auth,
   selector: '#dropin-container'
 }, function (errCreate, instance) {
    document.getElementById("submit-button").addEventListener('click', function () {
        if(errCreate) {
            console.log("Error", errCreate);
            return;
        }
        instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
            if (requestPaymentMethodErr) {
                console.log('Error', requestPaymentMethodErr);
                return;
            }
            return payload.nonce;
        });
    });
});
}

这个函数似乎在工作,返回数据和付款随机数等等。在我实际渲染小部件的(单独的)dart 文件中,我这样声明函数:

// EXTERNAL JAVASCRIPT ==========================================

@JS()
external void initBraintree(auth);

@JS()
external payment(String auth);

这似乎有效,它在单击按钮时调用函数,这很好。问题是当我将这个异步函数称为 returns 一个承诺时,理论上 dart 不应该知道如何处理这个但是,幸运的是他们有一个名为 promiseToFuture 的方法应该处理这个。我是这样用的:

  Future<BraintreeDropInResult> start(BuildContext context, BraintreeDropInRequest request) async {
    // create div with html embedded
    String htmlL = """<div id="checkout-message"></div>
        <div id="dropin-container"></div>
    <button id="submit-button">Submit payment</button>""";
    var paymentDiv = html.DivElement()..appendHtml(htmlL);

    // attach to payment container
    ui.platformViewRegistry.registerViewFactory('braintree-container', (int viewId) => paymentDiv);

    // call js function
    var promise = payment(request.clientToken);
    String nonce = await promiseToFuture(promise);
 ...

然而它就是行不通。 JavaScript 函数似乎正在返回一个 promise 对象,但是 promiseToFuture 函数从不等待它,每次都立即 returns null。

已经为此工作了一段时间,终于感觉非常接近,但这对我来说是一个真正的刺,所以非常感谢任何帮助!

你可以这样做。即创建一个承诺,一旦一切正常——并且单击按钮——它将用随机数解决。

当然,这只对第一次点击按钮有效。因为,一旦承诺被解决或拒绝,它就不会再改变它的状态和结果。

async function payment(auth) {
  return new Promise((resolve, reject) => {
    braintree.dropin.create({
        authorization: auth,
        selector: '#dropin-container'
      },
      (createError, instance) => {
        //probably there is no need to attach the eventhandler
        //if the was an error 
        if (createError) {
          console.log("Error", createError);
          return reject(createError);
        }
        document.getElementById("submit-button").addEventListener("click", 
          () => {
            instance.requestPaymentMethod((rpmError, payload) => {
              if (rpmError) {
                console.log("Error", rpmError);
                return reject(rpmError);
              }
 
              resolve(payload.nonce);
            });
          });
      }
    );
  });
}