经常看到的一个题目,特此求解
gpt的写法是:
- async/await
- callback function
一般也就是那两三种
async
function asyncFunction() {
return new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
const result = 'Hello, world!';
resolve(result);
}, 1000);
});
}
// 调用测试
(async function() {
console.log('Start');
const result = await asyncFunction();
console.log('End');
})();
回调函数
function asyncFunction(callback) {
// 模拟异步操作
setTimeout(() => {
const result = 'Hello, world!';
callback(result);
}, 1000);
}
// 调用测试
(function syncFunction() {
console.log('Start');
asyncFunction(function(result) {
console.log(result);
console.log('End');
});
})();
Generator生成器
function asyncFunction() {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const result = 'Hello, world!';
resolve(result);
}, 1000);
});
}
// 将异步操作封装在生成器中(不大推荐,不如上面两种简洁明了)
function* syncFunction() {
console.log('Start');
const result = yield asyncFunction();
console.log(result);
console.log('End');
}
// 执行生成器函数(手动迭代)
const generator = syncFunction();
function handleAsync(iterator) {
const { value, done } = iterator.next();
if (done) return;
if (value instanceof Promise) {
value.then((result) => {
handleAsync(iterator);
}).catch((error) => {
console.error(error);
});
}
}
handleAsync(generator);
借助第三方框架,例如:
synchronize.js
fibers.js
那就要把所有会触发异步的代码移除或修改(正常不会有这样丧心病狂的需求吧)
例如:
第三方框架链接
synchronize
fibers
一般来说将异步代码改为同步写法比较常见的就是封装后的各种回调函数以及借助Promise
来实现,包括async/await
在内实际上只是改变了代码的写法使其看起来更加同步,但底层运行逻辑仍是异步的,这里提一个以前开发项目用过的node
扩展deasync.js,核心功能是用c++
写的,在node
环境下需要经过node-gyp
编译后才能使用,底层逻辑是通过强制刷新一遍事件循环来达到真正意义上的异步代码同步化执行,使用方法也十分简单粗暴:
var deasync = require('deasync');
// 经过deasync包装后的exec方法已变成同步函数
var cp = require('child_process');
var exec = deasync(cp.exec);
try {
console.log(exec('ls -la'));
} catch (error) {
console.log(error);
}
// done会如预期那样在最后打印出来
console.log('done');
var data, done = false;
// asyncFunction是一个请求数据的接口
asyncFunction(p1, function cb(res) {
data = res;
done = true;
});
require('deasync').loopWhile(function() { return !done; });
// 调用loopWhile等待后此时已经能获取到赋值后的data
function SyncFunction() {
var ret;
setTimeout(function() {
ret = "hello";
}, 3000);
// 调用sleep方法睡眠一段时间直到ret被赋值
while (ret === undefined) {
require('deasync').sleep(100);
}
// 该函数将会返回hello
return ret;
}
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答5.2k 阅读✓ 已解决
1 回答3.4k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
严格来说异步没有办法变为同步。更多时候提问者应该是想说让代码写起来像同步。那么这样其实就只有一种那就是
async/await
;因为其他的方式都不太像同步。宽泛点问应该是怎么设计一个异步逻辑。那就有很多种了。1、回调函数
2、
promise
3、队列。其实
promise
也是队列4、
promise
+generator
=>async/await