js同步异步问题,怎么调用带callback函数的时候改成同步
发布于 7 年前 作者 vlwq 9810 次浏览 来自 问答
var doExe = function (a , callback) {
    setTimeout(function () {
        console.log(a)
        if(callback) callback
    }, 100 * Math.random())
}
var aTest = function (num) {
    for(var i=0 ; i<num ; i++){
          doExe(i)
    }
}

aTest(10)

需求:

doExe是带个callback的函数,要求执行aTest(10)输出0123456789
注意: guaTest函数可以随意改动,但是doExe 不能改动(不知道有没有记错doExe的代码,如果可以改直接用promise包一下解决了)
目前方案(目前我自己尝试出可以用递归解决,如下面)
var doExe = function (a, callback) {
    setTimeout(function () {
        console.log(a)
        if (callback) {
            callback()
        }
    }, 100 * Math.random())
}
var max = 9
var aTest = function (index) {
    doExe(index, () => {
        index < max && aTest(++index)
    })
}
aTest(0)

那个面试官是用队列+doExe.apply解决了,当时没看懂,请问这个怎么做的,或者说请问有什么其他解决方案

9 回复
var doExe = function (a, callback) {
    setTimeout(function () {
        console.log(a)
        if (callback) {
            callback()
        }
    }, 100 * Math.random())
};

//async
(async () => {
  for (let i = 0; i < 10; i++) {
    await new Promise(resolve => doExe(i, resolve));
  }
})();

//不让用async
let p = new Promise(res => doExe(0,res));
for (let i = 1; i < 10; i++) {
  p = p.then(() => new Promise(res => doExe(i, res)));
}

//es5
var i = 0;
var aTest = function(){
  i < 10 && doExe(i++, aTest);
}
aTest();

//令人窒息的操作
for(let t = 0; t < 10; t++){
  Math.random = () => t;
  doExe(t);
}

还可以用events,

来自酷炫的 CNodeMD

var doExe = function(a, callback) {
    setTimeout(function() {
        console.log(a)
        if (callback) callback()
    }, 100 * Math.random())
};

+function(num) {
    var cur = 0;
    function next() {
        if (cur > num-1) return;
        doExe(cur++, next);
    }
    next();

}(10);

方法2

var doExe = function(a, callback) {
    setTimeout(function() {
        console.log(a)
        if (callback) callback()
    }, 100 * Math.random())
};

+function(num) {
    var cur = num - 1;
    var last =null;
    while (cur >= 0) {
        last = (function(_cur, _last) {
            return function() {
                doExe(_cur, _last);
            }
        })(cur--, last);
    }
    return last;
}(10)()

@dislido 非常感谢!也看明白了。。。。。重新认识了promise的感觉。膜一发

@godghdai 这个看起来好像类似与yield/generator, 谢谢,自己搜索一下

令人窒息的操作哈哈哈 @godghdai

不用async

'use strict';
module.exports = { async_machine };

function run({value, done}) {
  if (done) return value;
  else {
    value.then(_value => {
      return run.call(this, this.next(_value));
    });
  }
}

function async_machine(fn) {
  const gen = fn();
  return run.call(gen, gen.next());
}


async_machine(function *() {
  for (let i = 0; i < 10; i++) {
    yield new Promise(next => doExe(i, next));
  }
});


function doExe(n, callback) {
  setTimeout(function () {
    console.log(n);
    if (callback) callback();
  }, 100 * Math.random());
}

回到顶部