promise,await,async,generator(3)(一天一个问题16)

await,async
promise链式调用(下一步调用需要上一步的结果)
new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 3000); // (*)
}).then(function(result) { // (**)
  console.log(result); // 1
  return result * 2;   // 将返回的promise状态改为resolved 
}).then(function(result) { // (***)
  console.log(result); // 2
  return result * 2;
}).then(function(result) {
  console.log(result); // 4
  return result * 2;
});
async(立即执行返回一个promise,不阻碍主线程,可以用.then链式调用)

函数前面的async一词意味着一个简单的事情:这个函数总是返回一个promise,如果代码中有return <非promise>语句,JavaScript会自动把返回的这个value值包装成promise的resolved值;调用就像普通函数一样调用,但是后面可以跟then()了

async function fn() {
    return 1
}
fn().then(alert) // 1
//等同
async function f() {
  return Promise.resolve(1)
}
f().then(alert) // 1
await(等待promise.resolve的消息,阻塞,不处理错误消息)

直到await等到到一个结果后才会往下执行

async function f() {    // await 只能在async函数中使用
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => resolve('done!'), 1000)
    })
    let result = await promise   //  直到promise返回一个resolve值(*)才会执行下一句
    alert(result) // 'done!' 
}
f()

在这里插入图片描述

1)表明程序里面可能有异步过程: async关键字表明程序里面可能有异步过程,里面可以有await关键字;当然全部是同步代码也没关系,但是这样async关键字就显得多余了;
2)非阻塞: async函数里面如果有异步过程会等待,但是async函数本身会马上返回,不会阻塞当前线程,可以简单认为,async函数工作在主线程,同步执行,不会阻塞界面渲染,async函数内部由await关键字修饰的异步过程,工作在相应的协程上,会阻塞等待异步任务的完成再返回;
3)async函数返回类型为Promise对象: 这是和普通函数本质上不同的地方,也是使用时重点注意的地方;
(1)return newPromise();这个符合async函数本意;
(2)return data;这个是同步函数的写法,这里是要特别注意的,这个时候,其实就相当于Promise.resolve(data);还是一个Promise对象,但是在调用async函数的地方通过简单的=是拿不到这个data的,因为返回值是一个Promise对象,所以需要用.then(data => { })函数才可以拿到这个data;
(3)如果没有返回值,相当于返回了Promise.resolve(undefined);
4)无等待 联想到Promise的特点,在没有await的情况下执行async函数,它会立即执行,返回一个Promise对象,并且绝对不会阻塞后面的语句,这和普通返回Promise对象的函数并无二致;
5)await不处理异步error: await是不管异步过程的reject(error)消息的,async函数返回的这个Promise对象的catch函数负责统一抓取内部所有异步过程的错误;async函数内部只要有一个异步过程发生错误,整个执行过程就中断,这个返回的Promise对象的catch就能抓取到这个错误;
5)async函数的执行: async函数执行和普通函数一样,函数名带个()就可以了,参数个数随意,没有限制,也需要有async关键字;只是返回值是一个Promise对象,可以用then函数得到返回值,用catch抓整个流程中发生的错误;

1)await只能在async函数内部使用:不能放在普通函数里面,否则会报错;
2)await关键字后面跟Promise对象:在Pending状态时,相应的协程会交出控制权,进入等待状态,这是协程的本质;
3)await是async wait的意思: wait的是resolve(data)的消息,并把数据data返回,比如下面代码中,当Promise对象由Pending变为Resolved的时候,变量a就等于data,然后再顺序执行下面的语句console.log(a),这真的是等待,真的是顺序执行,表现和同步代码几乎一模一样;

const a = await new Promise((resolve, reject) => {
    // async process ...
    return resolve(data);
});
console.log(a);

4)await对于失败消息的处理: await只关心异步过程成功的消息resolve(data),拿到相应的数据data,至于失败消息reject(error),不关心不处理;对于错误的处理有以下几种方法供选择:
(1)让await后面的Promise对象自己catch;
(2)也可以让外面的async函数返回的Promise对象统一catch;
(3)像同步代码一样,放在一个try…catch结构中;
5)await对于结果的处理: await是个运算符,用于组成表达式,await表达式的运算结果取决于它等的东西,如果它等到的不是一个Promise对象,那么await表达式的运算结果就是它等到的东西;如果它等到的是一个Promise对象,await就忙起来了,它会阻塞其后面的代码,等着Promise对象resolve,然后得到resolve的值,作为await表达式的运算结果;虽然是阻塞,但async函数调用并不会造成阻塞,它内部所有的阻塞都被封装在一个Promise对象中异步执行,这也正是await必须用在async函数中的原因

实例
//需要返回结果了在执行setState
fetchUser = async (value) => {
        this.lastFetchId += 1;
        const fetchId = this.lastFetchId;
        this.setState({ data1: [], fetching: true });
        var newData = await Util.getmenbers2(value)
        console.log(newData)
        if(newData instanceof Array){
            this.setState({ data1:newData, fetching: false });
        }
    };
export function getmenbers2(value){
    return new Promise((resolve, reject) => {
        Util.ajaxmode(`/api/project/members?keyword=${value}`, 'GET', undefined, undefined, { noPending: true }).then((response) => {
            if (response && response.length) {
                response.forEach(element => {
                    element.id = element.empno;//工号
                    if (element.empno) {
                        element.name = element.name + '(' + element.empno + ')';
                    }
                });
            }
            resolve(response) 
        });
      })
}

解读:
await等待的是resolve消息,等到到消息以后才会往下执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值