Prefácio
Um objeto de promessa pode ser entendido como uma operação a ser executada (geralmente usada para operações assíncronas). Depois de usar o objeto Promise, o código pode ser organizado de uma maneira de chamada para tornar o código mais intuitivo. Além disso, como a existência de um método como o Promise.TUAL pode ser simples de executar várias operações ao mesmo tempo.
A ascensão da promessa é porque, em chamadas de método assíncrono, as funções de retorno de chamada geralmente ocorrem uma após a outra. Essa situação levou ao surgimento de problemas de pirâmide de retorno de chamada. O código não é apenas difícil e não bonito de escrever, mas também dificulta as pessoas que leem o código de entender quando o problema é complicado.
Como exemplo:
db.save (dados, function (dados) {// Faça algo ... db.save (data1, function (data) {// faça algo ... db.save (data2, function (dados) {// faça algo ... feito (data3); // retorna dados})});}); Suponha que exista uma operação de salvamento de banco de dados e uma solicitação exige que os dados sejam salvos três vezes em três tabelas. Então nosso código é semelhante ao código acima. O que devo fazer se houver um problema no segundo db.save neste momento? Com base nessa consideração, precisamos usar a lógica como try...catch em cada camada de retorno de chamada. Esta é a fonte de todo o mal, e também é um ponto em que o nó foi amplamente criticado no começo.
Outra desvantagem é que, supondo que não haja dependência de frente e back entre nossas três defesas, ainda precisamos esperar que a função anterior seja executada antes que a próxima etapa seja executada, e as três defesas não podem ser paralelizadas e retornar o resultado necessário após as três salvamentos. (Ou requer habilidades para implementá -lo)
Infelizmente, quando comecei a me envolver no nó, escrevi muitos infernos assim.
Mais tarde, porque ainda escrevi mais código de front-end, entrei em contato com o ES6 e encontrei uma ferramenta poderosa para resolver o abismo de retorno de chamada.
De fato, muito antes da promessa do ES6, Q, quando.js, Bluebird e outras bibliotecas já haviam construído suas próprias rodas de promessa com base no padrão de promessa (consulte Promise/A+).
(Eu li um artigo e acho que faz sentido. Diz que você não deve estender objetos nativos embutidos. Essa abordagem não pode ser orientada para o futuro. Então, aqui está uma dica: seja cauteloso ao usar bibliotecas que estendem a promessa nativa.)
Apenas a promessa nativa é discutida aqui.
ES6 Promessa
Promessa status do objeto
Antes de explicar a promessa em detalhes, vamos primeiro tomar uma teoria:
A especificação Promise/A+ estipula que o objeto Promise é uma máquina de estado finita.
Tem três estados:
1. pending (execução)
2. fulfilled (bem -sucedido)
3. reject
Onde pending é o estado inicial, fulfilled e rejected são os estados finais (o estado final indica que o ciclo de vida da promessa terminou).
A relação de transição do estado é:
pendente-> cumprido, pendente-> rejeitado.
Vários eventos serão acionados como transições de estado (como eventos de execução bem -sucedidos, eventos de execução com falha etc.).
Formulário de promessa
A promessa se parece com a seguinte:
var promey = nova promessa (função func (resolver, rejeitar) {// faça algo, talvez assíncrono if (succcess) {return resolve (data);} else {return rejen (data);}}); prometo.then (function (dados) {// faz algo ... eg console.log (dados);}, function (err) {) {//A promessa variável aqui é uma instância do objeto Promise.
Quando o objeto Promise é criado, a lógica na função func será executada.
Quando a lógica é processada e não há erros, o retorno de chamada resolve passará o valor para um local especial. Onde está este lugar especial? Isso está então no código a seguir. Usamos a função de retorno then chamada para processar o resultado após resolve . Por exemplo, no código acima, simplesmente produzimos o valor para o console. Se houver um erro, reject -o na segunda função de retorno de chamada then processar o erro.
De acordo com a teoria acima da máquina de estado finita, sabemos que, ao executar o código da função de retorno de chamada no construtor da promessa, o estado está pending , o estado é fulfilled após resolve e o estado é reject após reject
Promessa fluxo de dados
O acima é o primeiro fluxo de dados de promessa.
O engraçado é que o método de promessa then ainda pode devolver um objeto de promessa, para que possamos usar o then para fazer o mesmo processamento.
Os dois funções de retorno de chamada no primeiro then determinam que tipo de objeto de promessa o primeiro then retorna.
Supondo que o primeiro retorno de chamada do primeiro then não retorne um objeto de promessa, o chamador do segundo then é o objeto de promessa original, exceto que seu valor de resolução se torna o valor de retorno da primeira função de retorno de chamada no primeiro.
Supondo que a primeira then a primeira função de retorno de chamada retorne um objeto de promessa, o segundo then o chamador se torna esse novo objeto de promessa e o segundo then o novo objeto Promise resolver ou rejeitar e executar o retorno de chamada.
Embora tenha poupado um pouco, sinto que ainda estou muito claro sobre isso. Haha ~
Se um erro for encontrado em qualquer lugar, o erro será entregue à segunda função de retorno de chamada then com a segunda função de retorno de chamada para lidar com isso. Pode -se entender que o erro reject para trás até que seja processado.
Além disso, o objeto Promise também possui uma catch de método, que aceita uma função de retorno de chamada para lidar com erros.
Agora mesmo:
Promise.catch (function (err) {// lide o err.})Supondo que o manuseio de erros seja semelhante, esse método pode lidar com erros centralmente e uniformemente. Portanto, outros métodos não requerem um segundo retorno de chamada ~
Controle promessas simultâneas
A Promise tem um "método estático" - Promise.all (observe que não é prometido.prototype). Este método aceita um elemento que é uma variedade de objetos de promessa.
Este método também retorna um objeto de promessa. Se todos os objetos de promessa na matriz forem resolve , os valores resolve serão usados como uma matriz como o valor resolve do objeto (promessa) do valor de retorno do método Promise.all e poderá ser processado pelo método then . Se alguma promessa na matriz for reject , o valor reject será o valor reject do valor de retorno Promise.all .
Um ponto muito opaco é:
A ordem do valor resolve (como mencionado acima, uma matriz) recebida pela primeira função de retorno de chamada do método then é a mesma que a ordem da matriz de parâmetros em Promise.all , e não em ordem cronológica.
Há também resolve método semelhante ao Promise.all Promise.race
Transforme outros objetos em objetos de promessa
O método Promise.resovle pode retornar um objeto de promessa como um parâmetro.
Existem duas situações:
Supondo que não exista um método .then Do parâmetro aprovado, o objeto Promise retornado se torna resolve e o valor resolve é o próprio objeto.
Supondo que o parâmetro passado possua um método then (chamado de objeto thenable ), o tipo desse objeto é alterado para prometer e then método se torna Promise.prototype.then o método.
A promessa é uma solução para assíncrona?
Finalmente, deixe -me dizer algo muito importante: a função da Promise é resolver o problema das pirâmides de retorno de chamada e, na verdade, não desempenha um grande papel no controle do processo assíncrono. Para realmente usar a promessa para controlar o processo assíncrono, também precisamos usar a função generator ES6. (Por exemplo, a implementação da biblioteca CO do TJ Master).
No entanto, o ES7 terá uma solução mais impressionante: async/await , que é semelhante ao CO, mas tem suporte nativo. Vamos esperar e ver.
Resumir
O exposto acima é sobre a promessa nativa no JavaScript ES6. Espero que o conteúdo deste artigo seja útil para todos para aprender ES6. Se você tiver alguma dúvida, deixe uma mensagem para se comunicar.