flutter web 与 js Promise 通信

245 阅读3分钟

启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

Flutter系列文章列表

  1. 2022年了,你还不会flutter!!!
  2. Flutter 第一课---flutter特点及组件开发
  3. Flutter 第二课---组件生命周期和App生命周期
  4. Flutter 第三课---状态管理之Provide
  5. Flutter 第四课---路由管理
  6. Flutter 第五课 --- 包管理器和资源管理
  7. Flutter 第六课 --- flutter网络请求
  8. Flutter 第七课 --- flutter 网络封装
  9. Flutter 第八课 ---使用 Flutter 构建 Web 应用
  10. 如何正确的在flutter中添加webview
  11. flutter原生 与 js 交互
  12. flutter web 与 js 交互

前言

为什么要来单独说一说这个话题。你在开发中是否存在这样的需求,你在设备端点击支付按钮,然后调起支付商家的页面,等支付完成之后把结果回传给你了。这里就需要使用Promise来等待支付结果。我们在开发中也经常使用这种方法来解决问题。上一节课中,我说过这是一个很深的坑,不知道有没有开发的同学知道这个痛点,我先卖个关子,等你看完你这篇文章,你就会茅塞顿开了。

js Promsie

js Promise 是什么?简单来讲,promise就是为了解决JavaScript异步编程的回调地狱问题。我们都知道JavaScript的执行环境是单线程。所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会阻塞其他任务。如果我们在页面加载完成之前执行一个耗时很长的任务,我们的页面就会出现长时间的白屏问题,这是我们作为程序员所不能容忍的。异步的出现完美解决了这个问题。如果任务需要等待,可先执行下一任务,等到第一个任务结果返回后再继续回调。

回调地狱是什么?

  • 在回调函数中嵌套回调,代码逐级向外递归,形成了回调地狱。

dart Promise

既然要相互通信,那必然dart中也存在promise,但结果是否定的,dart中不存在promise,我是我所说的第一坑。

第一个坑:dart中没有promise,dart中解决异步是用Future来实现,这时候就需要将promise转换成Future

如何转换

js端代码

let callBridge = function (msg) {
    try {
      handleMessage.postMessage(JSON.stringify(msg));
    } catch (error) {
      console.warn('callBridge -> error', error)
    }
}

//获取设备信息
function getDeviceInfo() {
  const msg = {
    function: 'DeviceInfo',
    params: {},
    callBack:"getDeviceInfoHandle"
  }
  callBridge(msg)  // 第二个坑
  return new Promise(function(resolve, reject) {
      let timer = setInterval(function(){
          if(deviceFlag){
             deviceFlag = false
             clearInterval(timer)
             resolve(nativDeviceData)
           }
      },500)
  })
}

第二个坑:js如何获取设备信息。

flutter端代码

import 'dart:convert';
import 'package:js/js.dart';
import "package:universal_html/js_util.dart";

@JS()
external getDeviceInfo();

static Future deviceInfo() async {
    var promise = getDeviceInfo();  
    // 调用Js的方法
    try {
      var result = await promiseToFuture(promise); // 第三个坑 
      var resultMap = json.decode(result);
      return resultMap;
    } catch (e) {
      print("getDeviceInfo错误信息是 $e");
    }
}

第三个坑

  • 不能直接在promiseToFuture的参数中传递getDeviceInfo(); 需要先接受,然后再进行传递,我在这里两眼一抹黑了三天。
  • 关于promiseToFuture文档看这里:api.flutter.dev/flutter/dar…

这里除了Future可以解决异步问题外,还可以使用其他方法,也就是说如果不使用Future,我们就需要将promise转换为所使用的方法,这里不展开讲,感兴趣的同学可以自行查询。

结束语

好了,关于flutter web 调用 js promise的学习到这里就告一段落,我不敢说我的方法就是最完美的,这里仅供参考,如果你觉得你的方法更完美,可以在评论区留下你的答案,我是与你们一起成长的小安子!