Залип, как дождаться event и решить промис только после этого event?

<script type="module">
    const sqlw = new Worker("...");
    sqlw.init = async ( w, e ) => {
        w.postMessage( { type: "open", messageId: "open", args: e } );
        w.onmessage = ( e ) => {
            if ( e.data.type === "sqlite3-api" && e.data.result === "worker1-ready" ){
                // ??????
            }
        };    
    }
    let e = await sqlw.init( sqlw, {filename: "test.db", flags: "cw", vfs: "opfs"} );
</script>
  • kevlarbeaver
    link
    fedilink
    arrow-up
    0
    ·
    11 months ago

    Тебе нужно не async использовать, а создать промис через new Promise и вручную его резолвить, когда приходит сообщение что воркер отработал.

    • AnoxemianOP
      link
      fedilink
      arrow-up
      0
      ·
      11 months ago

      Хуйня или годно?

          sqlw.init = async ( w, e ) => {
              let x = undefined;
              w.postMessage( { type: "open", messageId: "open", args: e } );
              w.onmessage = ( e ) => {
                  x = e;
              }
              return new Promise( resolve => {
                  setTimeout( () => { x !== undefined ? resolve( x ) : x = undefined; }, 200 );
              });
          }
      
      • kevlarbeaver
        link
        fedilink
        arrow-up
        0
        ·
        11 months ago

        Отредактировал изначальный код: <script type=“module”> const sqlw = new Worker(“…”); sqlw.init = (w, e) => { return new Promise((resolve) => { w.postMessage( { type: “open”, messageId: “open”, args: e } ); w.onmessage = ( e ) => { if ( e.data.type === “sqlite3-api” && e.data.result === “worker1-ready” ){ resolve(e.data); } };
        }); }; let e = await sqlw.init( sqlw, {filename: “test.db”, flags: “cw”, vfs: “opfs”} ); </script>

        • AnoxemianOP
          link
          fedilink
          arrow-up
          0
          ·
          11 months ago

          Еще вопрос, а как можно прибить функцию к объекту, типа init = sqlw.init.bind( sqlw, ...args ); ?

          • kevlarbeaver
            link
            fedilink
            arrow-up
            0
            ·
            11 months ago

            «Еще вопрос, а как можно прибить функцию к объекту, типа» Не очень понял, в чём вопрос. Ну типа ты вызываешь bind с аргументами на функции, - в итоге получаешь функцию с уже прибиндиными аргументами. Или что нужно? const init = sqlw.init.bind(sqlw, { filename: “test.db”, flags: “cw”, vfs: “opfs” }); let ready = await init(); console.log(ready); «Ну и до кучи, а в чем разница между» Концептуально оба варианта неправильные. Не столь важно, что postMessage находится внутри промиса, проблема тут в том, что если postMessage находится до подписки на событие (onmessage), то есть мизерная вероятность, что он успеет отработать до подписки - и ты ответа не получишь. Хотя, скорее всего, на практике твой код будет работать корретно просто из-за задержек сети, но лучше переписать как-то так: return new Promise((resolve) => { w.onmessage = ( e ) => { … }; w.postMessage( { type: “open”, messageId: “open”, args: e } ); }); или так: const p = new Promise((resolve) => { w.onmessage = ( e ) => { … };
            }); w.postMessage( { type: “open”, messageId: “open”, args: e } ); return p; Я просто местами поменял вызов postMessage и подписку на событие onmessage.

            • AnoxemianOP
              link
              fedilink
              arrow-up
              0
              ·
              11 months ago

              Ага, спасибо, кажется, вкурил.

              Или что нужно?

              По сути хочу как-то пофиксить прототип объекта, в данном случае воркера, добавить функций всяких, чтобы изнутри к самому воркерку можно было обращаться через this или еще как. Ну как-то глаз режет сама нотация sqlw.init( sqlw... ощущение сабя дегенератом прямо когда такое высираешь.

        • AnoxemianOP
          link
          fedilink
          arrow-up
          0
          ·
          11 months ago

          Ну и до кучи, а в чем разница между

          return new Promise((resolve) => {
              w.postMessage( { type: "open", messageId: "open", args: e } );
              w.onmessage = ( e ) => { ... };    
          });
          

          и

          w.postMessage( { type: "open", messageId: "open", args: e } );
          return new Promise((resolve) => {
              w.onmessage = ( e ) => { ... };    
          });