首先让我说我不询问有关异步/等待或承诺的任何问题,我知道这些概念,也知道我可以使用顶级
await
s为了更清楚地说明你可以在 Node js 中假设
fs.writeFileSync
,所以如果你有:
app.js:
1 console.log('first')
2 fs.WriteFileSync(file, data)
3 console.log('last')
javascript 将在行号“2”处停止,它将完成异步作业,然后它将记录“last”
现在,假设我有一个像
setTimeOut(() => { console.log('job done'); }, 500)
这样的异步工作,我想要的是创建一个像setTimeoutSync()
这样的函数,它可以像fs.writeFileSync
一样为我工作,所以如果我有:
index.js:
1 console.log('first')
2 setTimeoutSync()
3 console.log('last')
node index.js 应该为我提供如下所示的输出:
first
job done
last
有人可以帮我提供
setTimeoutSync()
函数的主体吗? (请考虑到我不想在我的index.js
中看到任何async或await关键字)
而且我不想使用任何第三方库
1-如果您正在进行模块化编程:(您的整个代码都在方法、对象和类中)
使用异步函数
let pr = new Promise (res => {
setTimeout(() => { console.log('job done'); res() }, 500);
})
async function asyncJob () { // do jobs in order
return await pr;
}
function syncJob_1 () { // do sync job
console.log('first');
}
function syncJob_2 () { // do sync job
console.log('last');
}
function startApp () {
syncJob_1();
asyncJob().then(syncJob_2);
}
startApp();
2-如果您的编程是非模块化的:
使用顶级等待
let pr = new Promise (res => {
setTimeout(() => { console.log('job done'); res() }, 500);
})
console.log('first');
await pr;
console.log('last');
所以,考虑到其他人的评论,我要回答我自己的问题
我们在nodejs世界中使用的javascript运行时是用c++编写的,如果我们想要制作像
setTimeoutSync()
这样的功能,我们需要修改Node.js事件循环实现,为此,我们应该在c++中进行
这项工作已经由“deasync”包完成,“Synchronized-promise”包依赖 deasync 来帮助您在 javascript 中完成此工作
我相信你也可以为自己制作一个非常简单的库来完成这样的事情:
synci.js:
class Jobs {
jobs = [];
jobIndex = 0;
jobsCount = 0;
constructor () {
}
doSync (func) {
this.jobs.push(func)
}
done () {
this.jobsCount = this.jobs.length;
this.doJob(0);
}
jobDid () {
this.jobIndex += 1;
if (this.jobsCount > this.jobIndex) this.doJob(this.jobIndex);
}
async doJob (index) {
let job = this.jobs[index];
job();
}
}
export default Jobs;
然后你可以拥有:
index.js:
import Jobs from './synci.js';
function setTimeoutSync (func) {
setTimeout(() => { console.log('job done'); func() }, 500);
}
const jobs = new Jobs();
jobs.doSync(() => { console.log('first'); jobs.jobDid(); });
jobs.doSync(() => { setTimeoutSync(()=>{ jobs.jobDid(); }) });
jobs.doSync(() => { console.log('last'); jobs.jobDid(); });
jobs.done();
上面的代码将产生以下输出:
first
job done // afer 0.5 Sec
last