JS tópico assíncrona

tópicos assíncronos: promessa e assíncrona, aguardam

1. síncronas e assíncronas

Síncrona e assíncrona: mensagem síncrona e assíncrona é um mecanismo de notificação

  • Sincronização: A chama B, negócio B com os resultados obtidos, antes de retornar para A. A No processo, os resultados têm sido pendente B, e antes não obter resultados, você precisa A (chamador) foi chamada em espera e confirmar se a resultados de retorno, obter resultados e, em seguida, continuar a descer. Antes de fazer uma coisa, não conseguimos os resultados, tem sido esperando por isso, esperar até que haja resultados, em seguida, fazer as seguintes coisas
  • Asynchronous: A chama B, sem esperar o resultado de B, A ou B é notificado através de função callback para notificação de status de alça. Fazer uma coisa, não espere pelos resultados de coisas, e então foi ocupado com qualquer outra coisa, com o resultado, e depois me diga por parte do Estado, ou processadas através da função de retorno. Tais como temporizadores, etc.

2.ES6 Promise objetos

Promessa objetos ES6 é um construtor para gerar exemplo promessa.

O chamado objeto Promessa é para representar um determinado eventos futuros (normalmente uma operação assíncrona) ocorrerá.

A sua vantagem é que, com o objecto Promise, pode ser operação assíncrona para o fluxo de operação síncrona expresso evitado retorno profundamente aninhada

  • Promessa de três estados: pendente, determinação e rejeitar
  • em seguida, o método e tentativa / captura - carregamento imagem

em seguida, o valor de retorno irá retornar uma nova objetos promessa, mas o estado terá várias situações:

  1. - em seguida, a função de retorno de chamada não retorna um valor, então um status será retornado: promessa de objetos resolvido
  2. - em seguida, o valor da função de retorno de chamada retorna não-promessa e, em seguida, retorna um status de: a promessa resolvido o objeto, o valor de retorno, adicionalmente, em seguida, passou para o próximo
  3. - em seguida, o valor de retorno da função de retorno de chamada é a promessa do objeto, então o objeto diretamente de volta a esta promessa, o estado específico pode ser definido por nossos próprios valores de entrega específica também definido por nossa própria

Três estados 3.Promise objeto

Promessa de três estados: pendente, resolvido e rejeitou

  1. Quando você cria um objeto Promise, que não realiza um sucesso nem mal sucedida, o status foi instaurada;
  2. Quando você cria um objeto Promise, se o objeto é um método executado com sucesso resolve (), então os retornos do estado resolvido;
  3. Promessa Ao criar um objecto, se o objecto for um método falha Rejeitar (), em seguida, o retorno de estado rejeitado, e erro;
  4. Quando você cria uma interface chamada bem-sucedida objeto ou pela promessa, seja para obter o status de resposta de Promise
    let p = new Promise((resolve,reject)=>{
        resolve("执行成功");
        // reject("执行失败");
    });

    //创建Promise对象时,即没有执行成功也没有执行失败,则状态为pending
    // console.log(p);//Promise {<pending>}

    //创建Promise对象时,如果对象中是执行成功方法resolve,则返回状态为resolved
    console.log(p);//Promise {<resolved>: "执行成功"}
    
    //创建Promise对象时,如果对象中是执行失败方法reject,则返回状态为rejected,且报错
    // console.log(p);//Promise {<rejected>: "执行失败"}

em seguida, o método objecto 4.Promise

  1. Em seguida, o método tem dois parâmetros, são funções;
  2. Em seguida, a primeira representação de parâmetros de um método realizado executada com êxito;
  3. A segunda representação de parâmetros, em seguida, o método falha após a execução;
  4. em seguida, o método pode ser chamado múltiplo (chamada cadeia), em seguida, em um valor de retorno de um sucesso, então, decidir ou o fracasso da implementação do método;
    let p = new Promise((resolve,reject)=>{
        // resolve("执行成功");
        reject("执行失败");
    });

    //
    p.then(info=>{
        //第一个参数,执行成功时调用
        console.log(info);//执行成功
    },msg=>{
        //第二个参数,执行失败时调用
        console.log(msg);//执行失败
    });

Exemplo: Picture Download

Se a imagem é baixado com sucesso tomar o primeiro método, se o download de imagens não consegue ir o segundo método

    let p = new Promise((resolve,reject)=>{
        let img = new Image();
        img.src = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565026842061&di=796e2653d34dfe2c98a7b8538fae2aca&imgtype=0&src=http%3A%2F%2Fimages.cnblogs.com%2Fcnblogs_com%2Fidotnet8%2Fchina.gif";
        
        img.onload = function(){
            resolve("图片加载成功");
        };
        img.onerror = function(){
            reject("图片加载失败");
        };
    });

    //
    p.then(success=>{
        console.log(success);//图片加载成功
    },error=>{
        console.log(error);//图片加载失败
    });

em seguida, o valor de retorno irá retornar uma nova objetos promessa, mas o estado terá várias situações:

  1.  em seguida, a função de retorno de chamada não retorna um valor , então um status será retornado: promessa de objetos resolvidos. Se o primeiro método não retorna um valor, então, é se este, em seguida, tomando o sucesso ou fracasso do método não irá afectar o método de execução da próxima seguida .
  2.  função de retorno, em seguida, retorna o valor da não-promessa , então ele irá retornar um status de: a promessa resolvido o objeto, o valor de retorno, adicionalmente, em seguida, passou para o próximo
  3. em seguida, a função de chamada de retorno valor de retorno é um auto-promessa de definições de objetos , em seguida, voltar a essa promessa diretamente estado alvo específico pode ser definido por nossos próprios valores de entrega específica também definido por nossa própria (neste momento, se a definição do objeto retornado de Promise determinação, informações sucesso será passado para a próxima, em seguida, o primeiro método, se ele retorna a partir da definição de objeto Promise rejeitar, envia uma mensagem de falha é transmitido para o segundo método, então o próximo).
  •  Quando, em seguida, nenhum valor de retorno (tempo, então nenhum valor de retorno, em seguida, todo o método padrão realizada simultaneamente): então ele irá retornar um status: promessa de objetos resolvido
    let p = new Promise((resolve,reject)=>{
        resolve("成功");
    });

    //then返回值一:如果then 方法没有返回值,就会返回一个状态为resolved的promise对象(即没有返回值默认走第一个成功的函数)
    p.then(success=>{
        console.log(success);//成功 第一个then方法没有返回值,所以默认走这个成功的方法
    },error=>{
        console.log(error);
    }).then(info=>{
        console.log(info);//undefined 由于第一个then没有返回值,而第二个then是根据第一个then的返回值接收信息的,所以info为undefined
    });
  • em seguida, retorna um valor, mas o valor é não-retorno a promessa: em seguida, retorna um status de: a promessa resolvido o objeto, o valor de retorno, adicionalmente, em seguida, passou para o próximo
    let p = new Promise((resolve,reject)=>{
        resolve("成功");
    });

    //then返回值二:当then方法有返回值,但返回值时非promise对象时,直接将返回值传递给下一个then
    p.then(success=>{
        console.log(success);//成功
        return success;
    },error=>{
        console.log(error);
    }).then(info=>{
        console.log(info);//成功 当then方法有返回值,但返回值时非promise对象时,直接将返回值传递给下一个then,所以这里的then方法得到的信息时第一个then的返回值
    });
  • em seguida, o valor da função de retorno de chamada de retorno é a promessa do objeto, então o objeto diretamente de volta a esta promessa, o estado específico pode ser definido por nossos próprios valores de entrega específica também definidas por nossa própria
  1.  Neste momento, se o objeto é um retorno personalizado Promise determinação, informações sucesso será passado para a próxima, em seguida, o primeiro método de
  2. Se o objeto é um retorno personalizado Promise rejeitar, ele irá falhar informações para um segundo método, então o próximo
    let p = new Promise((resolve,reject)=>{
        resolve("成功");
    });

    //then返回值三:当then方法有返回值,且返回值为Promise对象时,then方法直接返回这个Promise对象,具体的状态和值由我们自己决定
        // 此时如果自定义的Promise对象返回resolve,会将成功信息传递给下一个then的第一个方法
        // 如果自定义的Promise对象返回reject,会将失败信息传递给下一个then的第二个方法
    p.then(success=>{
        return new Promise((resolve,reject)=>{
            // resolve("第一个then方法成功");
            reject("第一个then方法失败");
        });
    },error=>{
        console.log(error);
    }).then(succMsg=>{
            console.log(succMsg);
    },errMsg=>{
        console.log(errMsg);
    });

função 5.Async e aguardar

  1. assíncrono funções e métodos esperam, usando vários métodos deve aguardar a execução bem-sucedida e, no caso dependente.
  2. Se o método função Await assíncrono e, em que uma execução Await falhar, então o programa já não é realizada.
  3. Aguardar a pluralidade de métodos, pode ser omitida uma final Await

Demanda: três dados pedido com um pedido dependente de 2, 3 2 pedidos o pedido. Ou seja, um pedido só pode ser executada após o pedido de execução 2 for concluída, a solicitação deve ser realizada ao longo de 2 para executar o pedido 3

    //Promise异步即以同步的方式实现异步
    async function fn(){
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求3");
                resolve();
            },1000);
        });
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求2");
                resolve();
            },1000);
        });
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求1");
                resolve();
            },1000);
        });
    }

    fn();

assíncrono funções e método await em que uma execução aguardam falhar, então o programa deixará de executar:

O método segundo rejeição a seguir representa a execução Await falhar, a execução falha, o pedido não prosseguirá 1

    async function fn(){
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求3");
                resolve();
            },1000);
        });
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求2");
                reject();
            },1000);
        });
        await new Promise((resolve,reject)=>{
            setTimeout(function(){
                console.log("请求1");
                resolve();
            },1000);
        });

método construtor em 6.Promise: resolve (), rejeitar (), todos (), raça ()

  1. Promise.resolve () retorna o status resolvido, eo personalizável informações sucesso
  2. Promise.reject () retorna o status rejeitado, informações de falha e pode personalizar
  3. Promise.all ([,, p1 p2 p3]) função com êxito se todos promessa, irá executar. Promise.all valor de retorno ([p1, p2, p3]), independentemente do método e, em seguida, chamar, em seguida, não há nenhum método de falhas de execução, estão tomando o primeiro parâmetro (de sucesso)
  4. Promise.race (), independentemente do sucesso ou fracasso de execução, qual método para executar o retorno que o valor de retorno do método. Quando Promise.race ([p1, p2, p3]) Retorna o valor do método, em seguida, chamar o método, em seguida, independentemente de qual método de sucesso ou fracasso, estamos dando o primeiro argumento, em seguida, o método de (bem-sucedida)

6.1 Promise.resolve () e rejeitar método () :

{
   let a = Promise.resolve("成功");
   console.log(a);//Promise {<resolved>: "成功"}

try {
    let b = Promise.reject("失败");
   console.log(b);//Promise {<rejected>: "失败"}并且报错
    throw "执行出错";
} catch (error) {
    console.log(error);//执行出错
}

Funções 6.2 Promise.all ([p1, p2, p3]) são todos sucesso promessa, irá realizar:

Promise.all valor de retorno ([p1, p2, p3]), independentemente do método e, em seguida, chamar, em seguida, não há nenhum método de falhas de execução, estão tomando o primeiro parâmetro (de sucesso)

    let p1 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve("p1执行成功");
        },1000);
    });

    let p2 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            // resolve("p2执行成功");
            resolve("p2执行失败");
        },1000);
    });

    let p3 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve("p3执行成功");
        },1000);
    });
    //Promise.all([p1,p2,p3])只有所有的promise对象都是返回resolved状态,才会成功
    let allP = Promise.all([p1,p2,p3]);
    console.log(allP);

    //Promise.all([p1,p2,p3])的返回值,再调用then方法无论有没有执行失败的方法,都是走第一个参数(成功)
    allP.then(msg=>{
        console.log("成功");
        // console.log(msg);//(3) ["p1执行成功", "p2执行成功", "p3执行成功"]
        console.log(msg);//(3) ["p1执行成功", "p2执行失败", "p3执行成功"]
        
    },info=>{
        console.log("失败");
    });

6.3Promise.race () ou, se a não executar uma implementação bem sucedida do retorno que o método primeiro dos quais do método de valor de retorno

Quando Promise.race ([p1, p2, p3]) Retorna o valor do método, em seguida, chamar o método, em seguida, independentemente de qual método de sucesso ou fracasso, estamos dando o primeiro argumento, em seguida, o método de (bem-sucedida)

    //Promise.race([p1,p2,...])方法中那个方法执行的最快,就返回哪个方法的返回值
    let p1 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve("p1执行成功");
        },1000);
    });

    let p2 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            // resolve("p2执行成功");
            resolve("p2执行失败");
        },500);
    });

    let p3 = new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve("p3执行成功");
        },3000);
    });
    let raceP = Promise.race([p1,p2,p3]);
    console.log(raceP);

    //Promise.race([p1,p2,p3])方法的返回值,再调用then方法时,无论其中的方法执行成功还是失败,都是走then方法的第一个参数(成功)
    raceP.then(msg=>{
        console.log("成功");//成功
        console.log(msg);//p2执行失败
        
    },info=>{
        console.log("失败");
        console.log(info);
    });

7. função de gerador e iterators

Subjacente assíncrona aguardam Generator é através gradual ao longo da evolução. Agora, com o método await assíncrona, basicamente Generator tem sido raramente usado. Mas pode ser usado alguma estrutura subjacente.

7.1 Iteração

  1. Iteração protocolo: especifica a iteração lógico e implementação de
  2. Iterator: lógica específica implementação iterativa
  3. Iterativo objetos: objetos que podem ser iteradas para - alcançar [Symbol.iterator] Método
  4. iteração declarações
  • para ... no: iteração objecto na sequência original pode ser inserida enumerado atributo ( matriz iterativo é o valor da chave )
  • para ... de: iterativo incorporada de acordo com o objecto objecto de dados é a iteração ( valor iterativo é uma matriz de valores )
  • Os objectos podem ser usados ​​para ... em malha, mas não pode ser usado para ... do ciclo, porque o objecto não é iteráveis, não existe nenhum método para alcançar Symbol.iterator

Iterators implementar o princípio [Symbol.iterator]:

obj[Symbol.iterator] = function(){
    return {
        next(){
            return {
                value: this.i++, 
                done: false 
            }
        }
    }
}

for ... in iteração é conjunto fundamental de valores :

    // for ...in 迭代的是数组的key值
    var arr = [1,2,3,4,5];
    for(var index in arr){
        console.log(index);//0,1,2,3,4
    }

para ... de iteração realização, valor iteração é uma matriz de valores :

    // for ...of 迭代的是数组的value值
    var arr = [1,2,3,4,5];
    for(var val of arr){
        console.log(val);//1,2,3,4,5
    }

Os objetos podem ser usados ​​para ... em loop, mas não pode ser usado para ... do ciclo, porque o objeto não é iterable, não implementado método Symbol.iterator:

//对象使用for ...in循环
    let obj = {
        a:1,
        b:2
    };
    for(let o in obj){
        console.log(o);//a b
    }

 usos de objetos para ... de erro laço direto:

//对象使用for ...of循环
    let obj = {
        a:1,
        b:2
    };
    for(let val of obj){
        console.log(val);//for...of迭代.html:22 Uncaught TypeError: obj is not iterable
    }

 

7.2 iterators implementar o princípio [Symbol.iterator]

  • protocolo de iteração: de acordo com o que é circulado, o loop pode obter algo, você pode definir o seu próprio;
  • Possui o iterador é iterable;
  • Iteração implementa o princípio é fixo;
    let obj = {
        a:1,
        b:2
    };

    //自定义实现迭代器
    obj[Symbol.iterator] = function(){
        //注意获取values和keys的方法时Object构造函数下的方法
        let vals = Object.values(obj);
        let keys = Object.keys(obj);
        
        let index = 0;
        return {
            next(){
                if(index>=keys.length){
                    return {
                        done:true
                    }
                }else{
                    //只想得到value值
                    // return {
                    //     value: vals[index++],
                    //     done:false
                    // }

                    //只想得到key值
                    // return {
                    //     value: keys[index++],
                    //     done:false
                    // }

                    //value值和key值想同时得到,就可以将value写成对象
                    return {
                        value: {
                            keys:keys[index],
                            //获取values时拖过keys获取,不要直接通过vals获取
                            values:obj[keys[index++]]
                        },
                        done:false
                    }
                }
            }
        };
    };

    for(let val of obj){
        console.log(val)
    }

resultados:

 

função 7.3Generator

Formalmente, Generator é uma função comum, mas existem duas características.

  1. Em primeiro lugar, a função entre os nomes de comandos e funções têm um asterisco .
  2. Em segundo lugar, as funções que utilizam a declaração de rendimento, de cada definição de membro de Walker, isto é, diferentes estados internos
  3. Depois de chamar a função Gerador não será executada imediatamente método e chamar a próxima função Generator () será executado

### Gerador de Sintaxe

// Generator 语法
    function* gen() { 
        yield 1;
        yield 2;
        yield 3;
    }

    //调用Generator函数不会立即执行
    let g = gen(); 
    console.log(g.next());//{value: 1, done: false}

 7.4Generator função assíncrona e associada

Desde a implementação de funções Gerador :

    função de co: personalizado função de gerador de automação chamador . A execução assíncrona antes da conclusão da execução de uma próxima função assíncrona é determinado com

    function*fn(){
        yield new Promise((resolve,reject)=>{
            setTimeout(()=>{
                console.log("a");
                resolve(1);
            },500);
        });
        yield new Promise((resolve,reject)=>{
            setTimeout(()=>{
                console.log("b");
                resolve(2);
            },500);
        });
        yield new Promise((resolve,reject)=>{
            setTimeout(()=>{
                console.log("c");
                resolve(3);
            },500);
        });
    }

    co(fn);
    function co(fn){
        let f = fn();
        next();
        function next(msg){
            let result = f.next();
            if(!result.done){//done为true时表示走完了
                result.value.then(info=>{
                    console.log(info,msg);//data表示上一步的返回信息
                    //上一个异步走完了,再执行下一个异步
                    next(info);
                });
            }
            
        }
        
    }

resultados:

 

8. conseguida por animação cadeia promessa (três maneiras)

Conseguido de três maneiras: o inferno de retorno de chamada (call repetido); em seguida, o método da Promessa; async / método await of Promise

Demanda: embalagens personalizadas estrutura de animação animação simples, para que a caixa da esquerda para a direita, em seguida, de cima para baixo, em seguida, da direita para a esquerda, em seguida, mudou-se 200px do-se inferior.

caminho do inferno 8,1 callback

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>链式动画</title>
    <style>
        body {
            margin: 0px;
            padding: 0px;
            position: relative;
        }
        #box {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
</head>
<body>
<div id="box"></div>
<script>
{
    //需求:自定义封装动画简易动画框架,让box 从左到右,再从上到下,再从右向左,再从下往上移动200px。

    let box = document.querySelector("#box");
    //需要给定参数,哪个元素,方向,移动到哪个位置
    let move =(el,attr,target,cb)=>{
        //获取元素起始位置
        let start = parseFloat(getComputedStyle(el)[attr]);
        //动画运动时,left或top有可能为往回走,就会是负方向
        let dir = (target-start)/Math.abs(start-target);
        let speed = 5;//元素移动的速度

        let count = 0;//动画帧编号,用于取消requestAnimationFrame

        //通过JS动画帧requestAnimationFrame让元素动起来
        cancelAnimationFrame(count);
        count = requestAnimationFrame(goTarget);
        function goTarget(){
            start += speed*dir;
            
            //注意这里使用点会有问题
            el.style[attr] = start + 'px';
                    
            //如果start等于了target就代表已经走完了,否则继续动画
            if(start == target){
                cancelAnimationFrame(count);
                cb&&cb();
            }else{
                //注意动画编号在动画帧再次调用时仍然要记录
                count = requestAnimationFrame(goTarget);
            }
        }        
        
    }

    //回调地狱
    //从左到右
    move(box,"left",200,function(){
        //从上到下
        move(box,"top",200,function(){
            // 从右向左
            move(box,"left",0,function(){
                move(box,"top",0,null);
            });
        });
    });
}
</script>
</body>
</html>

8,2, em seguida, o método para atingir animação cadeia

    //需求:自定义封装动画简易动画框架,让box 从左到右,再从上到下,再从右向左,再从下往上移动200px。

    let box = document.querySelector("#box");
    //需要给定参数,哪个元素,方向,移动到哪个位置
    let move =(el,attr,target)=>{
        //获取元素起始位置
        let start = parseFloat(getComputedStyle(el)[attr]);
        //动画运动时,left或top有可能为负
        let dir = (target-start)/Math.abs(start-target);
        let speed = 5;//元素移动的速度

        let count = 0;//动画帧编号,用于取消requestAnimationFrame

        //  使用Promise then方法必须返回Promise对象
        return new Promise((resolve,reject)=>{
            //通过JS动画帧requestAnimationFrame让元素动起来
            cancelAnimationFrame(count);
            count = requestAnimationFrame(goTarget);
            function goTarget(){
                start += speed*dir;
                console.log(start);
                
                //注意这里使用点会有问题
                el.style[attr] = start + 'px';
                        
                //如果start等于了target就代表已经走完了,否则继续动画
                if(start == target){
                    cancelAnimationFrame(count);
                    resolve();
                }else{
                    //注意动画编号在动画帧再次调用时仍然要记录
                    count = requestAnimationFrame(goTarget);
                }
            }        
        });
        
    }

    //使用Promise 的then方法实现动画异步执行
    move(box,"left",200)
    .then(item=>{
        //使用Promise 的then方法时,必须有return才能异步执行,否则全部then方法会同步执行
        return move(box,"top",200);
    })
    .then(item=>{
        return move(box,"left",0);
    }).then(item=>{
        move(box,"top",0);
    });

8,3 assíncrono método aguardam para alcançar animação cadeia

    //需求:自定义封装动画简易动画框架,让box 从左到右,再从上到下,再从右向左,再从下往上移动200px。

    let box = document.querySelector("#box");
    //需要给定参数,哪个元素,方向,移动到哪个位置
    let move =(el,attr,target)=>{
        //获取元素起始位置
        let start = parseFloat(getComputedStyle(el)[attr]);
        //动画运动时,left或top有可能为负
        let dir = (target-start)/Math.abs(start-target);
        let speed = 5;//元素移动的速度

        let count = 0;//动画帧编号,用于取消requestAnimationFrame

        //  使用Promise then方法必须返回Promise对象
        return new Promise((resolve,reject)=>{
            //通过JS动画帧requestAnimationFrame让元素动起来
            cancelAnimationFrame(count);
            count = requestAnimationFrame(goTarget);
            function goTarget(){
                start += speed*dir;
                
                //注意这里使用点会有问题
                el.style[attr] = start + 'px';
                        
                //如果start等于了target就代表已经走完了,否则继续动画
                if(start == target){
                    cancelAnimationFrame(count);
                    resolve();
                }else{
                    //注意动画编号在动画帧再次调用时仍然要记录
                    count = requestAnimationFrame(goTarget);
                }
            }        
        });
        
    }

    //使用Promise 的then方法实现动画异步执行
    async function runMove(){
        await move(box,"left",200);
        await move(box,"top",200);
        await move(box,"left",0);
        await move(box,"top",0);//最后一个await可以不写
    }
    runMove();

 

Publicado 95 artigos originais · Louvor obteve 115 · vista 120 000 +

Acho que você gosta

Origin blog.csdn.net/qq_34569497/article/details/98392151
Recomendado
Clasificación