javascript - 我如何等待回调来解决 JS 中的 promise ?同步 iOS WKWebView 和 JS

标签 javascript ios webkit wkwebview

最近我一直在尝试实现自己的LocalStorage实现,但我没有将数据存储在 JS 中,而是尝试将数据存储在 iOS native 端 NSUserDefaults 中.我将向您展示一些代码以明确我在说什么。我自己有这样的方法LocalStorage原型(prototype):

Storage.prototype.getItem = (function (key) {
    var that = this;
    var getValue = (function () {
        return new Promise(resolve => {
            // JS2Native request value for a specific key
            sendWebKitMessage(LS_GET_ITEM, { key: key });
                           
            console.log("new Promise for key=" + key + " timeInMs=" + Date.now());

            // create success callback
            that.onKeyValueReceived = function (keyValuePair) {
                if (keyValuePair !== null) {
                    console.log("onKeyValueReceived=" + keyValuePair.key + " value=" + keyValuePair.value);
                    resolve(keyValuePair.value);
                }
                else {
                    console.log("onKeyValueReceived=null for=" + key);
                    resolve(null);
                }
            };
        });
    });

    // handle async response from the Native side
    var waitFuntion = (async function () {
        var value = await getValue();
        console.log("value="+value);
        return value;
    });
    return waitFuntion();
});

// Native2JS helper methods
Storage.prototype.pasKeyValuePair = function (key, value) {
    this.onKeyValueReceived(key, value);
};

getItem我假设当客户端调用它时,它将等待,直到 iOS native 端从 NSUserDefaults 获取该值。并通过 Storage.prototype.pasKeyValuePair 传递给 Storage方法。

但实际上它看起来像 sendWebKitMessage(LS_GET_ITEM, { key: key }) 时那样被调用的“线程”没有被阻塞,客户端可以多次调用该方法,并且回调无法正常工作。

我是一个 JS 新手,我希望它能像互斥体一样工作。这实际上可以在 JS 中实现吗?还是我构建的东西完全错误? 我计划仅使用 vanilla JS 来完成此操作。

最佳答案

我想我明白你想做什么。如果我错了,请纠正我。 是的,我们可以在处理其他代码之前等待 Storage.getItem。但是,为此我们需要在调用 getItem 时使用 async-await。

请检查此代码:

var Storage = function() {};
Storage.prototype.getItem = function(key) {
  var promise = new Promise(function(resolve, reject) {
    //Fetch your item here and resolve the value. setTimeout is just for example.
    setTimeout(function() {
      resolve("Some value goes here.");
    }, 2000);
  });
  return promise;
};
(async function() {
  var storage = new Storage();
  console.log("I am called BEFORE Storage.getItem");
  var item = await storage.getItem("key");
  console.log(item);
  console.log("I am called AFTER Storage.getItem");

  console.log("Storage.getItem second time");
  item = await storage.getItem("key");
  console.log(item);

  //do something else
})();

这不会等待 Storage.getItem:

var storage = new Storage();
console.log("I am called BEFORE Storage.getItem");
var item = storage.getItem("key");
console.log(item);
console.log("I am called AFTER Storage.getItem");

请查看@CodePen https://codepen.io/animatedcreativity/pen/5a295fc445f97022b75c37189bf875fd


我无法测试你的代码。 但是,这是我能理解的。 我假设 getValue 的 Promise 正在正确解析。 错误在于以下行:var value = await getValue();。它不等待任何事情,因为它没有什么可等待的。它立即获取 Promise 对象。

那么,请试试这个:

    var waitFuntion = (async function () {
        var value;
        await getValue().then(function(_value) {
            value = _value;
        });
        console.log("value="+value);
        return value;
    });

这确保等到 getValue 的 Promise 实际解析该值。

关于javascript - 我如何等待回调来解决 JS 中的 promise ?同步 iOS WKWebView 和 JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53570830/

相关文章:

javascript - 如何在类中使用 If

javascript - 多个 insertRules 到一个 CSS 样式标签

ios - UITableview 下的滑动工具栏

ios - 栏按钮项目无法执行操作 Swift

javascript - 刷新页面和在 webkit 浏览器中输入页面有什么区别吗?(棘手)

c++ - html5 d3d 应用程序菜单/hud

javascript - 交换 Chrome 中所选选项卡内容中的一些单词

javascript - 如何获取点击标签的位置?

ios - UIPopover 中的 UIDatePicker

css - margin-top 不适用于最新版本的 safari 和 chrome(webkit)中按钮的子元素