js同步异步问题,怎么调用带callback函数的时候改成同步
发布于 8 年前 作者 vlwq 10395 次浏览 来自 问答
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());
}
回到顶部

AltStyle によって変換されたページ (->オリジナル) /