如何制作像 writefilesync 这样的同步函数,不使用回调,也不使用承诺

问题描述 投票:0回答:1

首先让我说我询问有关异步/等待或承诺的任何问题,我知道这些概念,也知道我可以使用顶级

await
s
但是
我想制作“单个函数”来阻止其主线程上的javascript(无论如何,我知道它是单线程的)

为了更清楚地说明你可以在 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关键字)

而且我不想使用任何第三方库

javascript multithreading asynchronous async-await callstack
1个回答
-1
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.