setTimeout(() => { //堆代码 duidaima.com //等待0.2s之后再做具体的业务操作 this.doSomething(); }, 200); this.setState({ count: res.count, }, () => { //在更新完count之后再做具体的业务操作 this.doSomething(); });Promise
let promise = new Promise((resolve, reject) = >{ reject("对不起,你不是我的菜"); }); promise.then((data) = >{ console.log('第一次success' + data); return '第一次success' + data }, (error) = >{ console.log(error) }).then((data2) = >{ console.log('第二次success' + data2); }, (error2) = >{ console.log(error2) }). catch((e) = >{ console.log('抓到错误啦' + e); });await/async
async function asyncDemoFn() { const data1 = await getData1(); const data2 = await getData2(data1); const data3 = await getData3(data2); console.log(data3) } await asyncDemoFn()
// 堆代码 duidaima.com 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} // 终于轮到我了上面代码的函数 foo 是一个协程,它的厉害的地方就是 yield 命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield 命令是异步两个阶段的分界线。协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。它的最大优点,就是代码的写法非常像同步操作,如果去除 yield 命令,简直一模一样。
const checkAuth = () => { return new Promise((resolve)=>{ setTimeout(()=>{ resolve('checkAuth1') },1000) }) } const checkAddress = () => { return new Promise((resolve)=>{ setTimeout(()=>{ resolve('checkAddress2') },2000) }) } var steps = [checkAuth,checkAddress] function* foo(checkList) { for (let i = 0; i < checkList.length; i++) { let x = yield checkList[i](); console.log(x); } } var stepsGen = foo(steps) var run = async (gen)=>{ var isFinnish = false do{ const {done,value} = gen.next() console.log('done:',done) console.log('value:',value) const result = await value console.log('result:',result) isFinnish = done }while(!isFinnish) console.log('isFinnish:',isFinnish) } run(stepsGen)种类对比
3. callback 让我们有了基本的方式去处理异步情况,Promise 告别了 callback 的回调地狱并且增加 resolve,reject 和 catch 等方法让我们能处理不同的情况,generator 增加了对于异步的可操作性,类似一个状态机可暂时停住多个异步的执行,然后在合适的时候继续执行剩余的异步调用,await/async 让异步调用更加语义化,并且自动执行异步
getData1().then((resData1) => { getData2(resData1).then((resData2) => { getData3(resData2).then((resData3)=>{ console.log('resData3:', resData3) }) }); });碰到这样的情况我们可以试着用 await/async 方式去解这种有多个深层嵌套的问题。
async function asyncDemoFn2() { const resData1 = await getData1(); const resData2 = await getData2(resData1); const resData3 = await getData3(resData2); console.log(resData3) } await asyncDemoFn2()异步循环
Promise.all([getData1(),getData2(),getData3()]).then(res={ console.log('res:',res) })顺序执行
const sources = [getData1,getData2,getData3] async function promiseQueue() { console.log('开始'); for (let targetSource in sources) { await targetSource(); } console.log('完成'); }; promiseQueue()2.使用 async/await 配合 while
//getData1,getData2,getData3 都为promise对象 const sources = [getData1,getData2,getData3] async function promiseQueue() { let index = 0 console.log('开始'); while(index >=0 && index < sources.length){ await targetSource(); index++ } console.log('完成'); }; promiseQueue()3.使用 async/await 配合 reduce
//getData1,getData2,getData3 都为promise对象 const sources = [getData1,getData2,getData3] sources.reduce(async (previousValue, currentValue)=>{ await previousValue return currentValue() },Promise.resolve())4.使用递归
const sources = [getData1,getData2,getData3] function promiseQueue(list , index = 0) { const len = list.length console.log('开始'); if(index >= 0 && index < len){ list[index]().then(()=>{ promiseQueue(list, index+1) }) } console.log('完成'); } promiseQueue(sources)