Eu tenho usado o ES6 Promise.
Normalmente, uma promessa é construída e usada assim
new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});
Mas eu tenho feito algo como abaixo para levar a decisão para fora por uma questão de flexibilidade.
var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});
E depois
onClick = function(){
outsideResolve();
}
Isso funciona bem, mas existe uma maneira mais fácil de fazer isso? Caso contrário, é uma boa prática?
javascript
promise
es6-promise
Morio
fonte
fonte
Promise
deve ser executado de forma síncrona para permitir "exportar" as duas funções.Respostas:
Não, não há outra maneira de fazer isso - a única coisa que posso dizer é que esse caso de uso não é muito comum. Como Felix disse no comentário - o que você faz sempre funcionará.
Vale ressaltar que a razão pela qual o construtor de promessas se comporta dessa maneira é a segurança de lançamento - se uma exceção que você não previu acontecer enquanto seu código estiver sendo executado dentro do construtor de promessa, ele se transformará em uma rejeição, essa forma de segurança de lançamento - convertendo erros lançados em rejeições é importante e ajuda a manter um código previsível.
Por esse motivo de segurança, o construtor da promessa foi escolhido em detrimento dos diferidos (que são uma maneira alternativa de construção da promessa que permite o que você está fazendo) - quanto às melhores práticas - eu passaria o elemento e usaria o construtor da promessa:
Por esse motivo - sempre que você puder usar o construtor de promessa sobre a exportação das funções - eu recomendo que você o utilize. Sempre que você puder evitar os dois - evite os dois e encadeie.
Observe que você nunca deve usar o construtor de promessas para coisas como
if(condition)
, o primeiro exemplo pode ser escrito como:fonte
Promise
cadeia? Por exemplo, no meu caso particular, estou em um servidor, aguardando uma resposta específica do cliente (um aperto de mão SYN-ACK-kinda para garantir que o cliente atualize com êxito o estado).simples:
fonte
promiseResolve()
. A semântica de uma promessa é que ela sempre retorna um valor. Além disso, isso é funcionalmente o mesmo que o post do OP, não entendo que problema isso está resolvendo de maneira reutilizável.promiseResolve()
não lançará uma exceção. Você pode definir um.catch
no construtor e, não importa como o código o chame, o construtor.catch
será chamado. Aqui está o jsbin demonstrando como isso funciona: jsbin.com/yicerewivo/edit?js,consoleUm pouco atrasado para a festa aqui, mas outra maneira de fazer isso seria usar um objeto adiado . Você tem essencialmente a mesma quantidade de clichê, mas é útil se você deseja contorná-los e possivelmente resolver fora de suas definições.
Implementação ingênua:
Versão ES5:
fonte
resolve|reject
são atribuídos lexicamente ou por meio debind
. Esta é apenas uma implementação simples do objeto adiado jQuery que existe desde 1.0 (ish). Funciona exatamente como uma promessa, exceto que não há segurança no lançamento. O ponto principal desta questão era como salvar algumas linhas de código ao criar promessas.Deferred
obsoleto?Uma solução criada em 2015 para minha estrutura. Eu chamei esse tipo de promessa de tarefa
fonte
Gostei da resposta do @JonJaques, mas queria dar um passo adiante.
Se você ligar
then
e, emcatch
seguida, oDeferred
objeto, ele implementará completamente aPromise
API e poderá tratá-la como promessa eawait
como tal.fonte
Um método auxiliar aliviaria essa sobrecarga extra e proporcionaria a mesma sensação do jQuery.
O uso seria
O que é semelhante ao jQuery
Embora, em um caso de uso, essa sintaxe nativa simples seja adequada
fonte
Estou usando uma função auxiliar para criar o que chamo de "promessa simples" -
E eu estou usando assim -
Veja o exemplo completo de trabalho -
Mostrar snippet de código
Edit: Eu criei um pacote NPM chamado flat-promessa e o código também está disponível no GitHub .
fonte
Você pode agrupar a promessa em uma classe.
fonte
Muitas das respostas aqui são semelhantes ao último exemplo deste artigo . Estou armazenando em cache várias promessas e as funções
resolve()
ereject()
podem ser atribuídas a qualquer variável ou propriedade. Como resultado, sou capaz de tornar esse código um pouco mais compacto:Aqui está um exemplo simplificado de uso desta versão de
defer()
para combinar umaFontFace
carga Promise com outro processo assíncrono:Atualização: 2 alternativas, caso você queira encapsular o objeto:
e
fonte
const result = await deferred.promise;
A resposta aceita está errada. É muito fácil usar o escopo e as referências, embora possa irritar os puristas do Promise :
Essencialmente, estamos capturando a referência à função de resolução quando a promessa é criada e retornamos para que ela possa ser definida externamente.
Em um segundo, o console exibirá:
fonte
Sim você pode. Usando a
CustomEvent
API para o ambiente do navegador. E usando um projeto emissor de eventos nos ambientes node.js. Como o snippet na pergunta é para o ambiente do navegador, aqui está um exemplo prático para o mesmo.Espero que esta resposta seja útil!
fonte
Nossa solução foi usar tampas para armazenar as funções de resolução / rejeição e anexar adicionalmente uma função para estender a promessa em si.
Aqui está o padrão:
E usando-o:
fonte
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... ainda funciona bem.Percebo que também sinto falta do padrão Adiado em certos casos. Você sempre pode criar uma sobre uma promessa do ES6:
fonte
Obrigado a todos que postaram neste tópico. Criei um módulo que inclui o objeto Defer () descrito anteriormente, bem como alguns outros objetos criados sobre ele. Todos eles utilizam o Promises e a pura sintaxe de retorno de chamada do Promise para implementar a manipulação de comunicação / evento dentro de um programa.
Fila: fila de execução baseada no encadeamento Promise.
rp = require("repeatable-promise")
https://github.com/CABrouwers/repeatable-promise
fonte
Eu escrevi uma pequena lib para isso. https://www.npmjs.com/package/@inf3rno/promise.exposed
Eu usei a abordagem método de fábrica outros escreveram, mas cancelou o
then
,catch
,finally
métodos também, então você pode resolver a promessa original por aqueles bem.Resolvendo Promessa sem executor de fora:
Correndo com o setTimeout do executor de fora:
Existe um modo sem conflito se você não deseja poluir o espaço para nome global:
fonte
Eu criei uma biblioteca chamada
manual-promise
que funciona como uma gota em substituição aPromise
. Nenhuma das outras respostas aqui funcionará como uma substituição nas substituiçõesPromise
, pois elas usam proxies ou wrappers.yarn add manual-promise
npn install manual-promise
https://github.com/zpxp/manual-promise#readme
fonte
Que tal criar uma função para seqüestrar a rejeição e devolvê-la?
fonte
Eu montei uma essência que faz esse trabalho: https://gist.github.com/thiagoh/c24310b562d50a14f3e7602a82b4ef13
aqui está como você deve usá-lo:
fonte
primeiro ative --allow-natives-syntax no navegador ou nó
fonte
Apenas mais uma solução para resolver o Promise de fora
Uso
fonte