簡體   English   中英

如何等待回調以解決 JS 中的承諾? 同步 iOS WKWebView 和 JS

[英]How do I wait for a callback to resolve a promise in JS? Sync iOS WKWebView and JS

最近我一直在嘗試實現我自己的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方法將其傳遞給 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 實際解析該值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM