Как мне ждать обратного звонка, чтобы решить обещание в JS?Синхронизация iOS WKWebView и JS - PullRequest
0 голосов
/ 01 декабря 2018

переполнение сообщества!

Недавно я пытался реализовать свою собственную реализацию LocalStorage, но вместо того, чтобы хранить данные в JS, я пытаюсь хранить данные на собственной стороне iOS в NSUserDefaults.Я покажу вам некоторый код, чтобы прояснить, о чем я говорю.У меня есть такой метод для моего собственного прототипа LocalStorage:

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 получит это значение из NSUserDefaults и передаст егоХранение с помощью метода Storage.prototype.pasKeyValuePair.

Но на самом деле это выглядит так, что когда вызывается sendWebKitMessage(LS_GET_ITEM, { key: key }), поток не блокируется, и клиент может вызвать этот метод еще несколько раз, и обратный вызов не работает должным образом.

Я новичок в JS, я ожидал, что он будет работать как мьютекс.Это действительно возможно реализовать в JS, или я строю что-то совершенно неправильно.Спасибо за преимущество!

PS Я планирую сделать это, используя только ванильный JS.

1 Ответ

0 голосов
/ 01 декабря 2018

Мне кажется, я понимаю, что вы хотите сделать.Пожалуйста, поправьте меня, если я ошибаюсь.Да, мы можем подождать Storage.getItem перед обработкой другого кода.Но для этого нам нужно использовать async-await при вызове getItem.

Пожалуйста, проверьте этот код:

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 разрешается правильно.Ошибка с линией: var value = await getValue();.Его ничего не ждет, потому что ему нечего ждать.Он сразу получает объект Promise.

Итак, попробуйте следующее:

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

Это гарантирует, что Promise getValue действительно разрешит значение.

...