비동기은 무엇인가?
async
기능은 Generator
문법적 기능. 키워드를 사용하여 async
내부적으로 함수를 사용하여 표현되는 await
비동기를 표현하기. 비교 Generator
, async
개선 된 기능은 다음과 같은 네 가지 사항은 다음과 같습니다
-
내장 액추에이터 .
Generator
드라이브 및에 의존해야 함수의 실행async
기능, 드라이브와 함께 제공됩니다 일반 함수 호출과 동일한 방식으로 호출 -
더 나은 의미 .
async
그리고await
비교*
하고yield
더 의미 -
더 넓은 적용 .
co
모듈 컨벤션,yield
단지 썽크 약속 오브젝트 뒤에 명령 또는 함수입니다. 그리고async
기능await
명령 후에, 또는 그 값을 약속 프리미티브 타입 일 수있다 (숫자, 문자열, 부울, 이번에는 동기 운전에 상당) -
반환 값은 약속이다 .
async
약속 함수 반환 값은 오브젝트를 직접 사용할 수있다 생성기 함수보다 편리 반복자를 반환 대상인then()
메소드 호출을
여기에서 요약 참조 : 이해 비동기 / await를
async
ES7은 새로운 기능, 실행을 중지하기 위해 다음 코드로 이어지는 스레드를 차단하지 않습니다, 현재 함수가 비동기 기능입니다 보여줍니다.
사용 방법
씌여 있기를 호출 할 수 있습니다 후
async function asyncFn() {
return 'hello world';
}
asyncFn();
이것은이 결과를 반환 비동기 기능을 나타냅니다
그것은 반환 promise
객체 상태 resolved
, 매개 변수 return
값입니다. 다음 함수 봐 그
async function asyncFn() {
return '我后执行'
}
asyncFn().then(result => {
console.log(result);
})
console.log('我先执行');
위의 결과를 출력하는 '我先执行'
것이 상기되어 있지만, 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));
우리는 내부 기능 던져 볼 异常
반환 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
- 직접 내부 미표시 변수 또는 기능을 포함.
- 오류 내부 던져
throw new Error
또는 반환reject
상태return Promise.reject('执行失败')
- 기능에있어서 실행 오류 (: 푸쉬를 이용하여 개체 ()) 등 ...
또 다른 점 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));
우리는 이상의 두 번째 줄 참조 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
나에게 실행의 성공 또는 실패를 then
나catch
async function awaitReturn() {
return await 1
};
awaitReturn().then(success => console.log('成功', success))
.catch(error => console.log('失败',error))
이 함수에서는, 거기 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();
返回reject后,后面的代码都没有执行了,以此迁出一个例子:
let last;
async function throwError() {
await Promise.reject('error');
last = await '没有执行';
}
throwError().then(success => console.log('成功', last))
.catch(error => console.log('失败',last))
其实
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))
这样的话,就可以继续往下执行了。
来个练习下
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===")
执行结果
我们一步步来解析
首先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
函数,所以返回的是一个字符串“return
testSometing
”。
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===")
执行结果
그리고 비교 예를 발견 promiseFn.then((val)=> console.log(val));
하기 전에 console.log(testFn1);
실행,이 때문에 이유는 testSomething()
이미입니다 async
반환 기능 Promise
당신이 그것을 기다려야 할 개체를 resolve
, 그래서 현재의 약속 푸시 큐, 그것은 반송 계속 test()
다음 코드를 실행하는 기능. 작업이, 약속 큐를 실행하기 시작했다 후 그래서 할 promise.then((val)=> console.log(val));
이 객체가 먼저 큐의 약속에 밀려 때문입니다.
, 점점 더 많은 사람들이 비동기 / 기다리고 궁극적 인 비동기 프로그래밍 솔루션이라고합니다 공부하고 있지만,이 방법에 대부분의 사람들은 매우, 실행 순서 JS 기다리고 후 컴파일하는 방법 내부 실행 이해되지 않는 당신이 희망 도움
- 그것은 비동기 코드를 작성하는 새로운 방법입니다. 프로그램 전에 비동기 코드 콜백과의 약속입니다.
- 그것은 약속에 따라, 그리고 약속은 비 블로킹과 동일하다.
- 비동기 / 더 동기 코드처럼 행동, 비동기 코드 모양을 허용 기다리고 있습니다. 이 곳의 힘이다.
저자 : 편집증ゝ
링크 : HTTPS : //juejin.im/post/5b1ffff96fb9a01e345ba704
출처 : 너기츠
저자가 저작권. 상업 무단 전재 저자 권한은 비상업적 무단 전재 소스를 표시하시기 바랍니다 문의하시기 바랍니다.
HTTPS : //my.oschina.net/u/2436852/blog/1833275 재현