#72 使用 generator 模拟 async/await


  • 0

    另外 报个bug吧,用户排行的分页有点问题,分页多了,后面几页没有用户,是不是在读取数据时,没有排除分数为0的用户啊~


  • 0

    @ScriptOJ

    Wrong Answer
    调用 wrapAsync 返回的函数所获得的 Promise 的 then 获得的数据 和 generator 返回的数据并不一致,你确定你 yield 出正确的数据了吗?

    报了以上错误,不造为何,在Chrome上跑以下代码结果是和题目一样的

    const wrapAsync = (generatorFn) => {
      return function (...p) {
        let g = generatorFn.apply(null, p)
        let n = g.next()
        var a = []
        while (!n.done) {
          a.push(n.value)
          n = g.next()
        }
        return new Promise(resolved => {
          resolved(Promise.all(a))
        })
      }
    }
    

    被题主的这个方法坑死了

    const run = wrapAsync(function * (lastName) {
      const data1 = yield getData('Jerry ' + lastName)
      const data2 = yield getData('Lucy ' + lastName)
      return [data1, data2]
    })
    

    一直以为data1和data2能接收到Promise,结果是undefined,最后自己创建个数组保存这些Promise,Chrome运行正确,这里却报了最上面那段错误,何解???????


  • 0

    @终天霸主 本来yield的返回值就是undefined呀,他只会根据你next函数的参数作为返回值的


  • 1

    写了好久

    const wrapAsync = (generatorFn) => {
      //是否循环
      let isLoop = true
      //返回的闭包
      return function resultFunc(){
        //得到iterator
        let argumentsArr = Array.prototype.slice.call(arguments)
        let generatorIterator = generatorFn(...argumentsArr);
        //闭包返回的promise
        return new Promise((resolve,reject)=>{
        function promiseFunc(promiseResult){
          let generatorIteratorObj = generatorIterator.next(promiseResult)
          if(!generatorIteratorObj.done){
            generatorIteratorObj.value.then(promiseFunc)
          }else{
            resolve(generatorIteratorObj.value)
          }
        }
          generatorIterator.next().value.then(promiseFunc);
        })
      };
    }
    

  • 0

    var wrapAsync=function(fun){
    	function donext(gen,a,v=undefined){
    		let ret=gen.next(v);
    		if(ret.value instanceof Promise){
    			ret.value.then(x=>donext(gen,a,x))
    		}else{
    			a(ret.value);
    		}
    	}
    	return function(inp){
    		return new Promise(
    			function(a,b){
    				var gen=fun(inp);
    				donext(gen,a);
    			}
    		);
    	}
    }
    

  • 0

    我理解的:

    const wrapAsync = (generatorFn) => /* TODO */
    (arg)=> new Promise((resolve, reject)=>{
       try {
        let _g = generatorFn(arg), _d = [], _s = _g.next().value
        while(_s !== undefined) {
           _d.push(_s)
    	  _s = _g.next().value	
        }
        resolve(_d) 
       }catch(e) {
         reject(e)
       }
    })
    

    执行:

    wrapAsync(function*(ar){
        let d1 = yield 90 + 1 + ar;
        let d2 = yield 80 + 2 + ar;
        yield 232 + ar;
        yield 1231 + ar
    })('test').then((res)=> console.log(res))

  • 0

    const wrapAsync = (gen) => {
        return function () {
          var g = gen([...arguments])
          const promise = new Promise((reslove, reject)=> {
            function next(data) {
              var res = g.next(data)
              if (!res.done) {
                res.value.then(next)
              } else {
                reslove(res.value)
              }
            }
            next()
          })
          return promise
        }
      }
    

  • 0

    const wrapAsync = gen => (...args) => new Promise((resolve, reject) => {
      const g = gen(...args)
    
      const next = val => {
        const res = g.next(val)
    
        if (res.done) {
          resolve(res.value)
        } else {
          res.value.then(next).catch(reject)
        }
      }
    
      return next()
    })
    

  • 1

    简单 O(∩_∩)O哈哈~

    const wrapAsync = (generatorFn) => {
      return (...args) => {
        return new Promise((resolve, reject) => {
          const g = generatorFn(...args);
          function go(result) {
            if (result.done) {
              resolve(result.value);
              return;
            }
            return result.value.then(val => {
              return go(g.next(val))
            })
          }
          go(g.next())
        })
      }
    }
    

  • 0

    catch((e) => {
              try {
                gen.throw(e);
              } catch(e) {
                reject(e)
              }
    答案里的异常处理,为何不能直接省去try catch呢?
    catch((e) => {
                reject(e)
              }
    

  • 0

    TJ的co函数的实现。考察对generator/yield、promise的理解与应用


  • 0

    const wrapAsync = (generatorFn) => (...args) => new Promise((resolve, reject) => {
      const g = generatorFn(...args)
    
      const next = (v) => {
        try {
          const r = g.next(v)
    
          if (r.done) {
            return resolve(r.value)
          }
    
          Promise.resolve(r.value).then(next, reject)
        } catch (err) {
          reject(err)
        }
      }
    
      next()
    })
    
    const wrapAsync = (generatorFn) => (...args) => {
      const g = generatorFn(...args)
    
      const next = (v) => {
        const r = g.next(v)
    
        if (r.done) {
          return Promise.resolve(r.value)
        }
    
        return Promise.resolve(r.value).then(next)
      }
    
      return next()
    }
    
    // test throw error in generator
    const run1 = wrapAsync(function * () {
      throw Error('lalala')
    })
    
    // test return a non promise value
    const run2 = wrapAsync(function * () {
      const a = yield 1
      const b = yield 2
    
      return [a, b]
    })
    
    

  • 0

    为什么会 报错‘调用 wrapAsync 返回的函数所获得的 Promise 的 then 获得的数据 和 generator 返回的数据并不一致,你确定你 yield 出正确的数据了吗?’
    const wrapAsync = (generatorFn) => {
    return (...param) =>{
    return new Promise ( (resolve,reject) => {
    let g = generatorFn(...param);
    return resolve(g.next().value)
    })
    }
    }


  • 0

    报错信息

    调用 wrapAsync 返回的函数所获得的 Promise 的 then 获得的数据 和 generator 返回的数据并不一致,你确定你 yield 出正确的数据了吗?

    可是自己测试的时候输出没错啊。附上代码:

    const wrapAsync = (generatorFn) => {
      return (...args) => {
            return new Promise(resolve => {
                let iterable = generatorFn.apply(null, args)
                let promiseArr = [...iterable].map((item, index) => {
                    item.then(val => {
                        promiseArr[index] = val
                        index == promiseArr.length - 1 ? resolve(promiseArr) : ''
                    })
                })
            })
        }
    }
    

登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待