Day04【JS】Promise、Async 和 Await

Promise

  • 保证执行之後才会做什麽事情
  • 对於「未来的值」的独立封装

状态

pending:尚未被fulfilled或rejected
fulfilled:成功完成 onFulfilled/resolve
rejected:操作失败 onRejected/reject

const delay = (s) => {
  return new Promise(resolve => {
    setTimeout(resolve,s); 
  });
};

delay().then(() => {
  console.log(1);     // 显示 1
  return delay(1000); // 延迟ㄧ秒
}).then(() => {
  console.log(2);     // 显示 2
  return delay(2000); // 延迟二秒
}).then(() => {
  console.log(3);     // 显示 3
});

处理成功&失败

delay()
    .then((response) => {
        if(response.result === 'success') {
            console.log('Success!')
        } else if(response.result === 'failure') {
            throw new Error('Whoops!');
        }
    })
    .catch((error) => {
        // ...
        console.log(error);
    });

Async 和 Await(ES6+)

  • async/await 基本上是一种把 Promise 的重新包装使用语法糖
  • await 一定要运行在 async function 内
~async function{
  const delay = (s) => {
    return new Promise(function(resolve){  // 回传一个 promise
      setTimeout(resolve,s);               // 等待多少秒之後 resolve()
    });
  };

  console.log(1);      // 显示 1
  await delay(1000);   // 延迟ㄧ秒
  console.log(2);      // 显示 2
  await delay(2000);   // 延迟二秒
  console.log(3);      // 显示 3
}();

开头的「~」表示直接执行这个 function,留意结尾有「()」表示立即执行

搭配 fetch 使用

fetch 最後回传的是 promise,很适合透过 async 和 await 操作

~async function(){
    console.log('开始抓气象');       // 先显示「开始抓气象」
    await fetch('气象局 json 网址')  // 带有 await 的 fetch
    .then(res => {
        return res.json();
    }).then(result => {
        let city = result.cwbopendata.location[14].parameter[0].parameterValue;
        let temp = result.cwbopendata.location[14].weatherElement[3].elementValue.value;
        console.log(`${city}的气温为 ${temp} 度 C`); 
    });
    console.log('总算结束了');       // 抓完气象之後再显示「总算结束了」
}();

Yield

用以暂停和恢复一个生成器函式(generator function)

function* foo() {
  for (let i = 1; i <= 3; i++) {
    let x = yield `再等一下,i = ${i}`;
    console.log(x);
  }
}

setTimeout(() => {
  console.log('终於轮到我了');
}, 1);

var a = foo();
console.log(a); // foo {<closed>}

var b = a.next();
console.log(b); // {value: "再等一下,i = 1", done: false}

var c = a.next();
console.log(c); // {value: "再等一下,i = 2", done: false}

var d = a.next();
console.log(d); // {value: "再等一下,i = 3", done: false}

var e = a.next();
console.log(e); // {value: undefined, done: true}

// 终於轮到我了

Promise.all

await Promise.all([task1(), task2(), task3()]);

当任一个阵列成员 rejected 则整个 Promise.all 立刻被拒绝。

Promise.allSettled

const responses = await Promise.allSettled([task1(), task2(), task3()]);
if(responses.every(response => response.result === 'success')) {
    console.log('Success!')
} else if(responses.some(response => response.result === 'failure')) { 
    responses.forEach(error => {
        console.log('error: ', error);
    });
}

绝对不会被 rejected,因此逻辑可以直接写在 then 或是不用写 try catch,需另外解析array内的resolved与rejected

参考资料


<<:  【Day04】Component 与 Props

>>:  <Day5>如何安装Shioaji套件?

Day2 - 自由接案也是一种职涯选择

事实上,在 11 年的职涯中,我上过 8 年的班,也就是说这 8 年我都是过着白天上班晚上赶案子的生...

第 22 集:Bootstrap 客制化 utilities(下)

此篇延续 Bootstrap 客制化 Sass utilities(上)最後尚未介绍的 gener...

倒数第3天

大家安安 突然发现有人关注 但是~ 前面的坑还没有补好 後面很难写 不过这篇我预计会写"算...

Day14 参加职训(机器学习与资料分析工程师培训班),Django实作 & 深度学习

上午: AIoT资料分析应用系统框架设计与实作 今日老师教学运用Django框架,将Bootstra...

Day 29 | SQLite资料库(四)

查询资料 query()方法 //查询资料 var number = "" va...