async – Como converter uma função baseada em promise para callback em JavaScript?

Podemos converter funções assíncronas que trabalham com callback para trabalharem com promises, como demonstrado nos exemplos abaixo:

callback:

const timeInMs = 1_000;

function asyncCallback(timeMs, callback) {
  setTimeout(() => callback(null, timeMs), timeMs);
}

console.log('first');

asyncCallback(timeInMs, (err, result) => {
  if (err) return console.log('Error: ', err);

  console.log('last');

  console.log('Time passed: ', result);
});

console.log('second');

Mudando para promise:

const timeInMs = 1_000;

function asyncCallback(timeMs, callback) {
  setTimeout(() => callback(null, timeMs), timeMs);
}

// função simples para converter callback em promise
function promisify(callback) {
  return function promisified(...args) {
    return new Promise((resolve, reject) => {
      const argsArray = (
        ...args,
        function (err, result) {
          if (err) return reject(err);

          resolve(result);
        },
      );

      callback(...argsArray);
    });
  };
}

// promisificando e convertendo a função asyncCallback
const asyncPromise = promisify(asyncCallback);

console.log('first');

asyncPromise(timeInMs).then((result) => {
  console.log('last');

  console.log('Time passed: ', result);
});

console.log('second');

// usando async/await
(async () => {
  const result = await asyncPromise(timeInMs);

  console.log('(async/await) Time passed: ', result);
})();

Repare que foi possível mudar de callback para promise graças a função customizada promisify().

A pergunta é:

  • Como converter uma função baseada em promise para callback, ou seja, fazer o oposto de promisify()? Algo como callbackify().

Tem uma função no Node.js chamada callbackify do core module util que faz já faz o caminho inverso:

import { callbackify } from 'util'

const timeInMs = 1_000

function asyncCallback (timeMs, callback) {
  setTimeout(() => callback(null, timeMs), timeMs)
}

function promisify (callback) {
  return function promisified (...args) {
    return new Promise((resolve, reject) => {
      const argsArray = (
        ...args,
        function (err, result) {
          if (err) return reject(err)

          resolve(result)
        },
      )

      callback(...argsArray)
    })
  }
}

const asyncPromise = promisify(asyncCallback)

const callbackFunction = callbackify(asyncPromise)

callbackFunction(timeInMs, (err, result) => {
  console.log('Time passed: ', result) // Time passed:  1000
})

Mas eu quero saber como seria feito uma função “na mão” (semelhante à promisify()), com passo a passo e com explicação detalhada, porque quero entender a lógica de implementação.

Esta minha dúivida é só uma prova de conceito e gostaria de saber…

php – dentro de selecionada por padrão baseada em variavel passada pela URL

Quero que o select de cursos tenha o valor(curso) selecionado por padrão quando o usuário acessar a pagina pelo link.

<html lang="pt-br">
    <head>
        <meta charset="utf-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.css">
        <link rel = "Stylesheet" type="text/css" href= "styles/menu.css">
        <link rel = "Stylesheet" type="text/css" href= "styles/paginas.css">
       <title>Biblioteca Solon Tavares</title>
    </head>
    <body>      
        <nav class="menu">
            <div id="logo">Biblioteca Solon Tavares</div>
                <ul>                
                    <li><a href="index.html" class="mna">Início </a></li>
                    <li><a href="#cursosc" class="mna mn1">Cursos 
                        <span class="baixo"></span></a>
                        <ul id="ulb" class="ul1">                           
                            <li><a href="paginas/ti.html" class="centra-vr">Técnico em Informática</a></li>
                            <li><a href="paginas/tr.html">Técnico em Redes de Computadores</a></li>
                            <li><a href="paginas/te.html">Técnico em Eletroeletrônica</a></li>
                        </ul>
                    </li>
                    <li><a href="#tccsc" class="mna mn2">TCCS 
                        <span class="baixo"></span></a>
                        <ul id="ulq" class="ul2">
                            <li><a href="paginas/tcc/tcc.php?cr=ti" class="centra-vr">Técnico em Informática</a></li>
                            <li><a href="paginas/tcc/tcc.php?cr=tr">Técnico em Redes de Computadores</a></li>
                            <li><a href="paginas/tcc/tcc.php?cr=te">Técnico em Eletroeletrônica</a></li>
                         </ul>
                    </li>
                </ul>
        </nav>
        <div id="cursosc" class="secoes">   
            <div class="crs-titulo">
                <h2>Cursos Técnicos</h2>
                <hr>
            </div>
            <div class="container">
                <div class="cr-ti curso">
                    <ul id="ti-li">                 
                    <li><i class="fa fa-3x fa-laptop text-primary"" style="visibility: visible;"></i></li>
                    <li><h3>Informática</h3></li>
                    <li><a href="paginas/ti.html#md1">Módulo 1</a></li>
                    <li><a href="paginas/ti.html#md2">Módulo 2</a></li>
                    <li><a href="paginas/ti.html#md3">Módulo 3</a></li>
                    <li><a href="paginas/ti.html#md4">Módulo 4</a></li>
                    </ul>
                </div> 
                <div class="cr-tr curso">
                    <ul id="tr-li">
                    <li><i class="fa fa-3x fa-wifi text-primary" style="visibility: visible;"></i></li>
                    <li><h3>Redes de Computadores</h3></li>
                    <li><a href="paginas/tr.html#md1">Módulo 1</a></li>
                    <li><a href="paginas/tr.html#md2">Módulo 2</a></li>
                    <li><a href="paginas/tr.html#md3">Módulo 3</a></li>
                    <li><a href="paginas/tr.html#md4">Módulo 4</a></li>
                    </ul>   
                </div>
                <div class="cr-te curso">
                    <ul id="te-li">
                    <li><i class="fa fa-3x fa-code-branch text-primary" style="visibility: visible;"></i></li>
                    <li><h3>Eletroeletrônica</h3></li>
                    <li><a href="paginas/te.html#md1">Módulo 1</a></li>
                    <li><a href="paginas/te.html#md2">Módulo 2</a></li>
                    <li><a href="paginas/te.html#md3">Módulo 3</a></li>
                    <li><a href="paginas/te.html#md4">Módulo 4</a></li>
                    </ul>
                </div>
            </div>
        </div>
        <div id="tccsc" class="secoes">
            <div class="crs-titulo">
                        <h2>Trabalhos de conclusão de curso</h2></li>
                        <hr>
                    </div>
            <div class="container">
                <div class="tcc curso">
                    <ul>
                        <li><i class="fa fa-3x fa-search text-primary" style="visibility: visible;"></i>
                        <i class="fa fa-3x fa-file-alt text-primary" style="visibility: visible;"></i></li>
                        <li><a href="paginas/tcc/tcc.php?cr=te">Técnico em Eletroeletrônica</a></li>
                        <li><a href="paginas/tcc/tcc.php?cr=ti">Técnico em Informática</a></li>
                        <li><a href="paginas/tcc/tcc.php?cr=tr">Técnico em Redes de Computadores</a></li>
                    </ul>   
                </div>
            </div>
        </div>
    </body>
</html>

Página que recebe e que será acessada:

<html lang="pt-br">
    <head>
        <meta charset="utf-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.css">
    
        <link rel = "Stylesheet" type="text/css" href= "../../styles/menu.css">
        <link rel = "Stylesheet" type="text/css" href= "../../styles/paginas.css">      
       <title>Biblioteca Solon Tavares</title>
    </head>
    <body>      
        <nav class="menu">
            <div id="logo">Biblioteca Solon Tavares</div>
                <ul>                
                    <li><a href="../../index.html" class="mna">Início   </a></li>
                    <li class="swmn"><a href="#" class="mna mn1" >Cursos 
                        <span class="baixo"></span></a>
                        <ul id="ulb" class="ul1">                           
                            <li><a href="../ti.html" class="centra-vr">Técnico em Informática</a></li>
                            <li><a href="../tr.html">Técnico em Redes de Computadores</a></li>
                            <li><a href="../te.html">Técnico em Eletroeletrônica</a></li>
                        </ul>
                    </li>
                    <li class="swmn"><a href="#" class="mna mn2">TCCS 
                        <span class="baixo"></span></a>
                        <ul id="ulq" class="ul2">
                            <li><a href="tcc.php" class="centra-vr">Técnico em Informática</a></li>
                            <li><a href="tcc.php">Técnico em Redes de Computadores</a></li>
                            <li><a href="tcc.php">Técnico em Eletroeletrônica</a></li>
                         </ul>
                    </li>
                    <li class="hdmn"><a href="#pqsbox" class="mna mn2">Pesquisa 
                        <span class="baixo"></span></a>                     
                    </li>
                    <li class="hdmn"><a href="#buscartcc" class="mna mn2">TCCS
                        <span class="baixo"></span></a>                     
                    </li>
                </ul>
        </nav>
        <div id="tccsc" class="secoes">
          <div id="pqsbox">
                <div id="tttcc" class="crs-titulo"> 
                    <h2>Busca por TCC</h2>
                    <hr>
                    </div>
                <div id="buscatc" class="container">
                    <?php $pdcurso=$_GET("cr")?>
                  <form action="tcc.php" method="POST">
                        <div class="bttbusc">  
                          <label for="buscatcc"><input type="search" id="buscatcc" name="pesquisatcc" placeholder="Ex: EcoGuaiba"></label>
                          <button id="buscar" type="submit" name="bsctcc"><i class="fa fa-lg fa-search text-primary" style="visibility: visible;"></i></button>
                        </div>
                        <select class="select" name="cursosl">  
                            <option class="ng" value ="">Curso:</option>
                            <option value = "tecnicoinformatica">TI</option>
                            <option value = "tecnicoeletronica">TE</option>
                            <option value = "tecnicoredes">TR</option>
                            <option value = "todos">Todos</option>
                        </select>
                        <select class="select" name="anocr"> 
                            <option class="ng" value ="">Ano:
                            <option value = "2020">2020</option>
                            <option value = "2019">2019</option>
                            <option value = "2018">2018</option>
                            <option value = "2017">2017</option>
                            <option value = "2016">2016</option>
                            <option value = "2015">2015</option>
                            <option value = "2014">2014</option>
                            <option value = "2013">2013</option>
                            <option value = "2012">2012</option>
                            <option value = "2011">2011</option>
                            <option value = "2010">2010</option>
                            <option value = "todos">Todos</option>
                        </select>  
                    </form>
                </div>
          </div>
        </div>
    </body>
</html>

Deve-se pegar a variavel pdcurso e verificar se ela corresponde a uma das 3 opcoes. Se sim selecionar essa opção quando a página for carregada.