Yang03 / blog

0 stars 0 forks source link

async/await in ES7 #8

Open Yang03 opened 8 years ago

Yang03 commented 8 years ago

正如大家知道的javascript 是单线程的,如果你要执行一个长时间运行的任务,那么将会进程阻塞, 引起其他事情的处理(ui挂起...),为了解决这个问题,javascript实现了异步,但是会严重依赖 回调。

callback hell

callback的问题是,会导致代码不易读,如果我在callback里嵌套callback

   function getData(url, callback) {
            var xhr = new XMLHttpRequest()
            xhr.open('GET', url)
            xhr.onreadystatechange = function() {
                if ( xhr.readyState == 4 && xhr.status == 200 ) {
                    callback(xhr.responseText)    
                }
            }
            xhr.send()
        }

        getData(a, function(){
            getData(b, function(){
                getData(c, function(){

                })    
            })
        })

我们改如何处理callback` hell, 在ES6中提供Promise,可以减少callback,它可以让代码的流程更清晰,如果我们用Promises,我可以改写上面的代码呢 ?

Promise

        var request = require('request-promise')
        request.get('a').then(function(data){
            console.log(data)
        })

Promise不仅让你的代码更短了,也更易读了,但是:

Promise的问题

如,我要获取所有的一级类目,然后获取所有二级类目

        var request = require('request-promise')
        var reqs = Promise.resolve()
        var requestData = null
        request.get('/categoryAll').then(function(data){
            reqs = data.forEach(function(parentId) {
                return p = request.get(/category/parentId).then(function(data){
                    requestData =  data
                })
            })        
        })

        reqs.then(function() {
            console.log(requestData)    
        })    

显然,prmise 在处理复杂的callback的时候,并没有很好的解决callback hell

Async Await

async 可以声明一个异步函数,此函数需要返回一个Promise对象,await 可以等待一个promise对象的
resolve,拿到返回值
    var request = require('request-promise')
     async function getCategoryAll(){
         return request.get('/categoryAll')
     }
     try {
         var data = await getCategoryAll()
         console.log(data)
     } catch(err) {
         console.log(err)
     }
当promise resolve 的时候,就可以拿到返回值, reject 的时候,也可以用try catch

async/await 最让人兴奋的是循环中的异步,还是上面那段代码
        var request = require('request-promise')
        var reqs = Promise.resolve()
        var arr = await request.get('/categoryAll')
        var promises = arr.map((parentId) {
            return  request.get(/category/parentId)
        })
        var results = [];
        for (let promise of promises) {
          results.push(await promise)
        }
        console.log(results)

        // or
        var results = await Promise.all(promises);
        console.log(results)
Yang03 commented 8 years ago

https://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html

https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html