簡體   English   中英

強制異步功能同步,無需等待異步

[英]Force asynchronous function to be synchronous without async await

我需要強制異步函數同步運行。 我的情況確實很復雜,所以我將嘗試解釋。

我正在開發與服務器通信的Ionic應用程序。

  • 在此應用程序中,我要收費Web服務生成的html頁面,並使用createComponent和compileModuleAndAllComponentsAsync創建一個新組件。

  • 在webservice發送的HTML中,有一些腳本標簽。 這些腳本是其他人定制的javascript,但是它們使用了我們創建的功能。 例如,我們創建了一個函數“ createdByUs”。 其他人可以使用它制作自定義javascript(下面的示例)。

  • “ createdByUs”功能是在Ionic應用程序之前創建的,許多人已經使用了它。 但是它在離子方面還有另一種行為,即如果該函數之前是同步的,則該行為是異步的。

  • 現在,我必須針對離子應用程序調整此功能,並且由於自定義腳本之前已創建,因此我必須編輯“ createdByUs”。 該代碼運行良好,只是異步的,因此其余的自定義代碼在“ createdByUs”結束之前執行

  <!-- our function -->
  <script type="text/javascript">
    inIonic = true;
    function createdByUs(){
        if(inIonic){
            new Promise(function(resolve, reject) {
              setTimeout(() => {
                console.log('Promise is created and consumed');
                resolve('Promise is created and consumed');
              }, 5000);
            });
        }else{
            console.log("nice synchronous code");
        }   
    }
  </script>

  <!-- custom functions made by other persons I can not modify -->
  <script type="text/javascript" id="customScript">
    createdByUs();
    console.log("other code that must wait for createdByUs");
  </script>

由於我無法修改自定義腳本,因此無法簡單地將“ cratedbyus”設置為異步,並在每個環境中使用await。 我的問題有解決方案嗎?

---編輯關於項目的一些精度:這是一種“頁面編輯器”,我們提供了圖形界面,以及一個供人們定義自定義腳本的區域。 我正在開發一個可以顯示這些頁面並且可以正常運行的應用程序。 但是某些功能在Ionic中不起作用,因此我必須重新定義它們。 為了運行離子代碼,我在createdByUs中調用了一個離子事件。 它運行良好,除了事件是異步的,而且它還在ngfor中添加了html元素,而當您修改ngfor的數組源時,ionic不會立即創建元素,因此在ngfor中生成html也是異步的。 無止境...

不,你不能那樣做。 如果您可以這樣做,則會產生各種問題(例如, setTimeout回調無法運行以實際解決promise,因為線程將在等待promise時被阻塞),因此它無法以任何方式完成,並且不會將來有可能。


你可能會說

但是為什么沒有辦法在非異步函數內部表現出與await相似的方式,以便將運行中的執行上下文存儲起來,從堆棧中刪除,然后在promise解析后再恢復呢?

可以肯定的是,可以做到這一點,但這會破壞函數從頭到尾的保證 ,換句話說,這會使每段代碼都不確定,這通常是一件壞事(換句話說:並發修改,亂序)執行等)。

但是,有“全局await建議”允許async功能之外的頂級await嗎?

是的,但這僅限於頂層,執行順序仍然是確定的(所有必需的模塊在運行之前取決於模塊的完成)。

您可以創建一些hack。

按原樣運行async函數,但返回promise。 然后,一旦諾言解決,就可以加載其他腳本。

myPromise.then(() => {
  const script = document.createElement('script')
  script.src = 'path/to/otherScript'
  document.getElementsByTagName('body')[0].appendChild(script)
})

暫無
暫無

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

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