js中异步编程的四种方法
http://www.ruanyifeng.com/blog/2012/12/asynchronous_javascript.html

对于异步操作,如果想让它控制台输出顺序为2、1、3,写成这样无论顺序是怎么样的,结果都是1、2、3

        setTimeout(() => {
            console.log(2)
        }, 2000);
        setTimeout(() => {
            console.log(1)
        }, 1000);
        setTimeout(() => {
            console.log(3)
        }, 3000);

如果想实现2、1、3的效果可以在每个定时器内嵌套另外的定时器,结果是2、1、3,但是在异步操作很多的时候会显得难以阅读,难以理解和修改,形成了callbackHell回调地狱(>>>>>)

        setTimeout(() => {
            console.log(2)
            setTimeout(() => {
                console.log(1)
                setTimeout(() => {
                    console.log(3)
                }, 3000);
            }, 1000);
        }, 2000);
        function f1(){
            return new Promise((res,rej)=>{
                setTimeout(() => {
                    console.log(2)
                    res()
                }, 2000);
            })
        }
        function f2(){
            return new Promise((res,rej)=>{
                setTimeout(() => {
                    console.log(1)
                    res()
                }, 1000);
            })
        }
        function f3(){
            return new Promise((res,rej)=>{
                setTimeout(() => {
                    console.log(3)
                    res()
                }, 3000);
            })
        }
        f1().then(()=>{
            return f2()
        }).then(()=>{
            return f3()
        }).then(()=>{
            console.log('end')
        })
//用promise.then处理异步操作,这样避免了回调地狱
// 2/1/3/end 2秒输出2然后1秒输出1最后三秒输出3和end
        async function fn() {
            await f1()
            await f2()
            await f3()
            console.log('end')
        }
         fn() 
// 可以使用async,await来简化异步操作,不需要再和上面一样使用promise.then来执行异步操作,
// 定义一个异步函数,使用await跟一个异步操作,await表示在这里等待异步操作返回结果,再继续执行。
// 输出结果和上面一样 2、1、3、end 2s输出一个2,再隔1s输出一个1,再隔3s输出一个3,接着输出end

async/await是什么?

我们创建了 promise 但不能同步等待它执行完成。我们只能通过 then 传一个回调函数这样很容易再次陷入 promise 的回调地狱。实际上,async/await 在底层转换成了 promise 和 then 回调函数。也就是说,这是 promise 的语法糖。每次我们使用 await, 解释器都创建一个 promise 对象,然后把剩下的 async 函数中的操作放到 then 回调函数中。async/await 的实现,离不开 Promise。从字面意思来理解,async 是“异步”的简写,而 await 是 async wait 的简写可以认为是等待异步方法执行完成。

async/await用来干什么?

用来优化 promise 的回调问题,被称作是异步的终极解决方案。

async/await内部做了什么?

async 函数会返回一个 Promise 对象,如果在函数中 return 一个直接量(普通变量),async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。如果你返回了promise那就以你返回的promise为准。
await 是在等待,等待运行的结果也就是返回值。await后面通常是一个异步操作(promise),但是这不代表 await 后面只能跟异步操作 await 后面实际是可以接普通函数调用或者直接量的。

await的等待机制?

如果 await 后面跟的不是一个 Promise,那 await 后面表达式的运算结果就是它等到的东西;如果 await 后面跟的是一个 Promise 对象,await 它会“阻塞”后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值作为 await 表达式的运算结果。但是此“阻塞”非彼“阻塞”这就是 await 必须用在 async 函数中的原因。async 函数调用不会造成“阻塞”,它内部所有的“阻塞”都被封装在一个 Promise 对象中异步执行。(这里的阻塞理解成异步等待更合理)

async/await在使用过程中有什么规定?

每个 async 方法都返回一个 promise 对象。await 只能出现在 async 函数中。

async/await 在什么场景使用?

单一的 Promise 链并不能发现 async/await 的优势,但是如果需要处理由多个 Promise 组成的 then 链的时候,优势就能体现出来了(Promise 通过 then 链来解决多层回调的问题,现在又用 async/await 来进一步优化它)。
链接:https://www.jianshu.com/p/8dccfa90ba59

async function async1() {
  console.log('2')
  const data = await async2()
  console.log(data)
  console.log('8')
}

async function async2() {
  return new Promise(function (resolve) {
    console.log('3')
    resolve('await的结果')
  }).then(function (data) {
    console.log('6')
    return data
  })
}
console.log('1')

setTimeout(function () {
  console.log('9')
}, 0)

async1()

new Promise(function (resolve) {
  console.log('4')
  resolve()
}).then(function () {
  console.log('7')
})
console.log('5')
1-2-3-4-5-6-7-async2返回的结果-8-9

Promise如何实现异步调用

图片说明

https://www.jianshu.com/p/72e36168944f