처분 할 수있는 당신이 비동기가 / 기다리고 있습니다 콜백 지옥을 해결하기 위해 알려

비동기은 무엇인가?

환영 메시지 토론

async기능은 Generator문법적 기능. 키워드를 사용하여 async내부적으로 함수를 사용하여 표현되는 await비동기를 표현하기. 비교 Generator, async개선 된 기능은 다음과 같은 네 가지 사항은 다음과 같습니다

  • 내장 액추에이터 . Generator드라이브 및에 의존해야 함수의 실행 async기능, 드라이브와 함께 제공됩니다 일반 함수 호출과 동일한 방식으로 호출

  • 더 나은 의미 . async그리고 await비교 *하고 yield더 의미

  • 더 넓은 적용 . co모듈 컨벤션, yield단지 썽크 약속 오브젝트 뒤에 명령 또는 함수입니다. 그리고 async기능 await명령 후에, 또는 그 값을 약속 프리미티브 타입 일 수있다 (숫자, 문자열, 부울, 이번에는 동기 운전에 상당)

  • 반환 값은 약속이다 . async약속 함수 반환 값은 오브젝트를 직접 사용할 수있다 생성기 함수보다 편리 반복자를 반환 대상인 then()메소드 호출을

여기에서 요약 참조 : 이해 비동기 / await를

asyncES7은 새로운 기능, 실행을 중지하기 위해 다음 코드로 이어지는 스레드를 차단하지 않습니다, 현재 함수가 비동기 기능입니다 보여줍니다.

사용 방법

씌여 있기를 호출 할 수 있습니다 후

async function asyncFn() {
  return 'hello world';
}
asyncFn();

이것은이 결과를 반환 비동기 기능을 나타냅니다

    1 

그것은 반환 promise객체 상태 resolved, 매개 변수 return값입니다. 다음 함수 봐 그

async function asyncFn() {
    return '我后执行'
}
asyncFn().then(result => {
    console.log(result);
})
console.log('我先执行');

 

1

위의 결과를 출력하는 '我先执行'것이 상기되어 있지만, asyncFn()제 실행하지만, 비동기 함수를 정의하고 있으며, 후속 기능의 구현에 영향을 미치지 않을 것이다.

 

이제 이해 async기본적인 사용법을, 그것의 특성 무엇인가?

async기본적으로 정의 된 내부 함수는 반환 promise내부 예외 또는 수익을 발생하는 경우, 객체를 reject, 기능의 원인이됩니다 promise실패로 상태를 reject.

 

 

 

async function e() {    
    throw new Error('has Error');
}
e().then(success => console.log('成功', success))   
   .catch(error => console.log('失败', error));

 

1

우리는 내부 기능 던져 볼 异常반환 reject, async심판이 실패 입력받은 후 기능 catch, 인쇄 출력에 의해 반환되는 오류가 발생했습니다.

 

 

 

async function throwStatus() {    
    return '可以返回所有类型的值'
}
throwStatus().then(success => console.log('成功', success))             
             .catch(error => console.log('失败', error));

 

 

 

 

//打印结果

成功 可以返回所有类型的值

 

async이 함수에 의해 리턴 된 값을 수신하고, 발견되지 异常또는 reject있을 수있다, 성공적인 판정 return, 각종 데이터의 값 false, NaN, undefined... 즉, 모든resolve

그러나, 다음과 같은 결과가 반환됩니다 async기능을 결정하는 실패를reject

  1. 직접 내부 미표시 변수 또는 기능을 포함.
  2. 오류 내부 던져 throw new Error또는 반환 reject상태return Promise.reject('执行失败')
  3. 기능에있어서 실행 오류 (: 푸쉬를 이용하여 개체 ()) 등 ...

또 다른 점 async은 결과가 할 위치를 return반환은, 다른 하나 실행 reject또는 resolved값이되는 undefine화살표 기능을 사용하는 것이 좋습니다.

나머지 결과를 판정 반환 resolved성공적으로 실행한다.

 

 

 

//正确reject方法。必须将reject状态return出去。
async function PromiseError() {    
   return Promise.reject('has Promise Error');
}

//这是错误的做法,并且判定resolve,返回值为undefined,并且Uncaught报错
async function PromiseError() {
  Promise.reject('这是错误的做法');
}

PromiseError().then(success => console.log('成功', success))              
              .catch(error => console.log('失败', error));

 

 

1

 

우리는 이상의 두 번째 줄 참조 Promise, 대상 인쇄를 상관 없어, 이것이 Chrome콘솔의 기본 동작, 우리는 일반적으로 할당 콘솔에서 같은 효과입니다. 마지막 경우, 执行语句또는 表达式전혀 return기본적으로, 반환 값 undefined, 약간의 실험.

 

 

 

var a = 1;
//undefined
------------------------------------------------------------
console.log(a);
//1
//undefined
------------------------------------------------------------
function a(){ console.log(1) }
a();
//1
//undefined
------------------------------------------------------------
function b(){ return console.log(1) }
b();
//1
//undefined
------------------------------------------------------------
function c(){ return 1}
c();
//1
------------------------------------------------------------
async function d(){
    '这个值接收不到'
}
d().then(success => console.log('成功',success));
//成功  undefined
//Promise { <resolved>: undefined }
-----------------------------------------------------------
async function e(){
    return '接收到了'
}
e().then(success => console.log('成功',success));
//成功  接收到了
//Promise { <resolved>: undefined }

 

마지막 줄은 Promise { <resolved> : undefined }반환이되기 때문이다 console.log하는 문장을 실행, 더 리턴 값이 없습니다.

 

 

 

d().then(success => console.log('成功',success)}
等同于
d().then(function(success){ 
            return console.log('成功',success);
        });

 

비동기를 통해 이해 Laijiangjiang이 기다리고 있습니다.

무슨 기다리고?

await의미 비동기 대기 (비동기 대기). 이 키워드에만 사용할 수 있습니다 async내부에 정의 된 함수를 사용하여. 모든 async기능은 기본을 반환 promise하고,이 promise모두를 해결할 값은 함수의 반환 값이며, async기능은 모든 내부 때까지 기다려야합니다 await명령 Promise개체를 실행, 상태 변화가 발생합니다.

비 유적으로, 다음 운전해야 학생, 비동기 학교 버스, 제나라를 기다리고 있습니다.

즉, 모든 기다릴 필요가있다 await, 함수가 종료 된 후에 말할 것이다 promise나에게 실행의 성공 또는 실패를 thencatch

 

 

 

async function awaitReturn() {     
    return await 1
};
awaitReturn().then(success => console.log('成功', success))
             .catch(error => console.log('失败',error))

 

1

이 함수에서는, 거기 await까지 기능이 비동기가 대기하는 await 1 이 단계를 통해 수행 반환 promise상태를 의심 할 여지가 결정된다 resolved.

很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入Promise队列(Promise的Job Queue)

来看个简单点的例子

 

 

 

const timeoutFn = function(timeout){ 
	return new Promise(function(resolve){
		return setTimeout(resolve, timeout);
               });
}

async function fn(){
    await timeoutFn(1000);
    await timeoutFn(2000);
    return '完成';
}

fn().then(success => console.log(success));

 

这里本可以用箭头函数写方便点,但是为了便于阅读本质,还是换成了ES5写法,上面执行函数内所有的await函数才会返回状态,结果是执行完毕3秒后才会弹出'完成'。

正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise。

也可以这么写

 

 

 

function timeout(time){
    return new Promise(function(resolve){
        return setTimeout(function(){ 
                    return resolve(time + 200)
               },time);
    })
}

function first(time){
    console.log('第一次延迟了' + time );
    return timeout(time);
}
function second(time){
    console.log('第二次延迟了' + time );
    return timeout(time);
}
function third(time){
    console.log('第三次延迟了' + time );
    return timeout(time);
}

function start(){
    console.log('START');
    const time1 = 500;
    first(time1).then(time2 => second(time2) )
                .then(time3 => third(time3)  )
                .then(res => {
                              console.log('最后一次延迟' + res );
                              console.timeEnd('END');
                             })
};
start();

这样用then链式回调的方式执行resolve

 

 

 

//打印结果

START
第一次延迟了500
第二次延迟了700
第三次延迟了900
最后一次延迟1100
END

 

用async/await呢?

 

 

 

async function start() {
    console.log('START');
    const time1 = 500;
    const time2 = await first(time1);
    const time3 = await second(time2);
    const res = await third(time3);
    console.log(`最后一次延迟${res}`);
    console.log('END');
}
start();

达到了相同的效果。但是这样遇到一个问题,如果await执行遇到报错呢

 

 

 

async function start() {
    console.log('START');
    const time1 = 500;
    const time2 = await first(time1);
    const time3 = await Promise.reject(time2);
    const res = await third(time3);
    console.log(`最后一次延迟${res}`);
    console.log('END');
}
start();

 

1

返回reject后,后面的代码都没有执行了,以此迁出一个例子:

 

 

 

let last;
async function throwError() {  
    await Promise.reject('error');    
    last = await '没有执行'; 
}
throwError().then(success => console.log('成功', last))
            .catch(error => console.log('失败',last))

 

1

 

其实

async函数不难,难在错处理上。

 

上面函数,执行的到await排除一个错误后,就停止往下执行,导致last没有赋值报错。

async里如果有多个await函数的时候,如果其中任一一个抛出异常或者报错了,都会导致函数停止执行,直接reject;

怎么处理呢,可以用try/catch,遇到函数的时候,可以将错误抛出,并且继续往下执行。

 

 

 

let last;
async function throwError() {  
    try{  
       await Promise.reject('error');    
       last = await '没有执行'; 
    }catch(error){
        console.log('has Error stop');
    }
}
throwError().then(success => console.log('成功', last))
            .catch(error => console.log('失败',last))

1

这样的话,就可以继续往下执行了。

 

 

来个练习下

 

 

 

 

function testSometing() {
    console.log("testSomething");
    return "return testSomething";
}

async function testAsync() {
    console.log("testAsync");
    return Promise.resolve("hello async");
}

async function test() {
    console.log("test start...");

    const testFn1 = await testSometing();
    console.log(testFn1);

    const testFn2 = await testAsync();
    console.log(testFn2);

    console.log('test end...');
}

test();

var promiseFn = new Promise((resolve)=> { 
                    console.log("promise START...");
                    resolve("promise RESOLVE");
                });
promiseFn.then((val)=> console.log(val));

console.log("===END===")

 

执行结果

1

 

我们一步步来解析

首先test()打印出test start...

然后 testFn1 = await testSomething(); 的时候,会先执行testSometing()这个函数打印出“testSometing”的字符串。

之后因为await会让出线程就会去执行后面的。testAsync()执行完毕返回resolve,触发promiseFn打印出“promise START...”。

接下来会把返回的Promiseresolve("promise RESOLVE")放入Promise队列(Promise的Job Queue),继续执行打印“===END===”。

等本轮事件循环执行结束后,又会跳回到async函数中(test()函数),等待之前await 后面表达式的返回值,因为testSometing() 不是async函数,所以返回的是一个字符串“returntestSometing”。

test()函数继续执行,执行到testFn2(),再次跳出test()函数,打印出“testAsync”,此时事件循环就到了Promise的队列,执行promiseFn.then((val)=> console.log(val));打印出“promise RESOLVE”。

之后和前面一样 又跳回到test函数继续执行console.log(testFn2)的返回值,打印出“hello async”。

最后打印“test end...”。

加点料,让testSomething()变成async

 

 

 

async function testSometing() {
    console.log("testSomething");
    return "return testSomething";
}

async function testAsync() {
    console.log("testAsync");
    return Promise.resolve("hello async");
}

async function test() {
    console.log("test start...");

    const testFn1 = await testSometing();
    console.log(testFn1);

    const testFn2 = await testAsync();
    console.log(testFn2);

    console.log('test end...');
}

test();

var promiseFn = new Promise((resolve)=> { 
                    console.log("promise START...");
                    resolve("promise RESOLVE");
                });
promiseFn.then((val)=> console.log(val));

console.log("===END===")

 

执行结果

1

그리고 비교 예를 발견 promiseFn.then((val)=> console.log(val));하기 전에 console.log(testFn1);실행,이 때문에 이유는 testSomething()이미입니다 async반환 기능 Promise당신이 그것을 기다려야 할 개체를 resolve, 그래서 현재의 약속 푸시 큐, 그것은 반송 계속 test()다음 코드를 실행하는 기능. 작업이, 약속 큐를 실행하기 시작했다 후 그래서 할 promise.then((val)=> console.log(val));이 객체가 먼저 큐의 약속에 밀려 때문입니다.

, 점점 더 많은 사람들이 비동기 / 기다리고 궁극적 인 비동기 프로그래밍 솔루션이라고합니다 공부하고 있지만,이 방법에 대부분의 사람들은 매우, 실행 순서 JS 기다리고 후 컴파일하는 방법 내부 실행 이해되지 않는 당신이 희망 도움

  1. 그것은 비동기 코드를 작성하는 새로운 방법입니다. 프로그램 전에 비동기 코드 콜백과의 약속입니다.
  2. 그것은 약속에 따라, 그리고 약속은 비 블로킹과 동일하다.
  3. 비동기 / 더 동기 코드처럼 행동, 비동기 코드 모양을 허용 기다리고 있습니다. 이 곳의 힘이다.

참고 : 자바 스크립트의 이해 비동기 / await를


저자 : 편집증ゝ
링크 : HTTPS : //juejin.im/post/5b1ffff96fb9a01e345ba704
출처 : 너기츠
저자가 저작권. 상업 무단 전재 저자 권한은 비상업적 무단 전재 소스를 표시하시기 바랍니다 문의하시기 바랍니다.

HTTPS : //my.oschina.net/u/2436852/blog/1833275 재현

추천

출처blog.csdn.net/weixin_34205076/article/details/92285528