What is async?
async
Function is Generator
syntactic sugar function. Use the keyword async
is represented internally using a function await
to represent asynchronous. Compared to Generator
, async
improved function is that the following four points:
-
Built-in actuator .
Generator
Execution of the function must rely on actuators andasync
function comes with actuators, calls the same way as with an ordinary function call -
Better semantics .
async
Andawait
compared to*
andyield
more semantic -
Broader applicability .
co
Module convention,yield
command or function behind only Thunk Promise objects. Andasync
functionawait
after the command, or it may be a value Promise primitive type (Number, string, boolean, but this time is equivalent to the synchronous operation) -
The return value is a Promise .
async
Promise function return value is an object, the object returns Iterator convenient than Generator function may be used directlythen()
method invocation
Summary References from here: understanding async / await
async
ES7 is a new feature, show the current function is asynchronous function, does not block the thread leading to subsequent code to stop running.
how to use
After affirms can be called up
async function asyncFn() {
return 'hello world';
}
asyncFn();
This indicates that this is an asynchronous function that returned results
It returns an promise
object state resolved
, a parameter return
value. Look at the following function that
async function asyncFn() {
return '我后执行'
}
asyncFn().then(result => {
console.log(result);
})
console.log('我先执行');
The results of the above is to print out '我先执行'
, although it is above the asyncFn()
first execution, but has been defined asynchronous functions, and will not affect the implementation of the follow-up function.
Now understand the async
basic usage, what is characteristic of it?
async
Internal function defined by default return an promise
object, if the internal throws an exception or returns reject
, will cause the function of promise
the state as a failure reject
.
async function e() {
throw new Error('has Error');
}
e().then(success => console.log('成功', success))
.catch(error => console.log('失败', error));
We see that throws an internal function 异常
return reject
, async
function after receiving, enter judgment fails catch
, the error returned by the print out.
async function throwStatus() {
return '可以返回所有类型的值'
}
throwStatus().then(success => console.log('成功', success))
.catch(error => console.log('失败', error));
//打印结果
成功 可以返回所有类型的值
async
Receives the value returned by the function, is not found 异常
or reject
is judged successful, there may be return
values of the various types of data, false
, NaN
, undefined
... In short, allresolve
However, the following results will return async
function determining failurereject
- Directly and internal containing undeclared variable or function.
- Internal throw an error
throw new Error
or returnreject
statusreturn Promise.reject('执行失败')
- Function method execution error (: Object using the push ()), and so on ...
Another point in async
where you want the results to be return
returned, otherwise either executed reject
or resolved
values are undefine
recommended to use the arrow functions.
The remaining results are returned determination resolved
executed successfully.
//正确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));
We see the second line of more than a Promise
target print, do not care, this is Chrome
the default behavior of the console, we usually assignment is the same effect in the console. If the last 执行语句
or 表达式
no return
return value, by default undefined
, a little experiment.
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 }
The last line Promise { <resolved> : undefined }
is because the return is console.log
executing a statement, there is no return value.
d().then(success => console.log('成功',success)}
等同于
d().then(function(success){
return console.log('成功',success);
});
Understanding over async, Laijiangjiang await.
What await that?
await
Meaning async wait (asynchronous wait). This keyword can only be used async
using a defined function inside. Any async
function will return the default promise
, and this promise
value will resolve all is the return value of the function, and the async
function must wait until all internal await
command Promise
objects executed, the state change will occur.
Figuratively, await students, async school bus, Qi, who must then drive.
That is, all have to wait await
after the function is finished, will tell promise
me the success or failure of execution then
orcatch
async function awaitReturn() {
return await 1
};
awaitReturn().then(success => console.log('成功', success))
.catch(error => console.log('失败',error))
In this function, there is a await
function, async will wait until await 1
this step will return to perform over promise
the state, no doubt, is determined 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===")
执行结果
And found a comparative example promiseFn.then((val)=> console.log(val));
prior to console.log(testFn1);
execution, the reason is because there testSomething()
is already a async
function that returns an Promise
object that you want to wait for it resolve
, so the current Promise push queue, it will continue to bounce test()
function executing subsequent code. After the task began to execute Promise queue, so do an promise.then((val)=> console.log(val));
Because this object is first pushed into the queue Promise.
More and more people are studying is said to be async / await the ultimate asynchronous programming solutions, but most people on this method is not very understanding how internal execution, execution order js compiled after await, hope you have help
- It is a new way to write asynchronous code. Before the program is asynchronous code callback and promise.
- It is based on the promise, and the promise is the same as non-blocking.
- async / await allow asynchronous code look, behave more like synchronous code. This is where its power.
References: understanding of JavaScript async / await
Author: paranoidゝ
link: https: //juejin.im/post/5b1ffff96fb9a01e345ba704
Source: Nuggets
copyright reserved by the authors. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.
Reproduced in: https: //my.oschina.net/u/2436852/blog/1833275