For example, there are three functions a, b, and c, all of which perform synchronization operations. In order to simplify it, I have simplified the synchronization operations
function c(m) {
m = m + 1;
return m;
}
function b(m) {
m = m + 1;
return c(m);
}
function a(){
let m = 0;
return b(m);
}
The output of executing a() is 2
But if the c function executes not a synchronous function, but an asynchronous operation, for example
function c(m) {
setTimeout(function () {
m = m + 1;
}, 1000)
return m;
}
When executing a(), if you want to correctly output 2, you must encapsulate c through promise or async,
Similar to
function promiseC(m) {
return new Promise((resolve, reject) => {
setTimeout(function () {
m = m + 1;
resolve(m);
}, 1000)
}
}
async function c(m) {
m = await promiseC(m);
return m;
}
Because c becomes an asynchronous function, b needs to call c, b must also be changed to asynchronous, and so on, a must also be changed to asynchronous
async function b(m) {
m = m + 1;
return await c(m);
}
async function a(){
let m = 0;
return await b(m);
}
a().then(function(data) {
console.log(data)
}) In this way, 2
can be outputIn order to output 2 correctly, I changed both a and b. I wonder if there is any other way to avoid changing a and b and achieve the correct output?
Since I didn’t consider asynchronous situations when I first wrote the code, functions like a and b are distributed in different files, and there are a lot of them. Now in order to allow c to perform asynchronous operations, it is too difficult to change. I don’t know if you have any other good methods?
The following is a newly added question
The above problems can be solved by directly returning the promise object in the answer below, but the actual code structure is more like this
function c(m) {
m = m + 1;
return m;
}
function b(m) {
m = m + 1;
let n = c(m)
n = n + 1
return n;
}
function a(){
let m = 0;
let k = b(m);
k = k + 1;
return k;
}
If I follow this method, I have to modify the return methods of a and b.
In order to allow a and b to return promise objects,
I don’t know if there is any way to achieve correct output without changing the a and b functions for such a structure. Methods
I’m sorry to tell you that node is explicitly asynchronous, so if you change a function from synchronous to asynchronous, then the functions that depend on it must also be changed. It is indeed a headache when refactoring, but you still have to endure it. Let's change it.
Refactoring like fibjs, which does not require the async keyword, is very worry-free. If you change c, you don’t need to change a and b, because implicit asynchrony does not require you to indicate it.
I still don’t understand Promise well enough. There is no need to change
b()
anda()
here.For function
c
, you only need to return apromise
object. When passing functionb
, this Promise object is directly returned synchronously. There is no need to change function b to make it an asynchronous function, because the asynchronous operation is in functionc In
, only synchronization operations are performed inb
. At this time, you need to capture this Promise in functiona
, so the code can be changed to thisSo, if the functions
a(), b()
do not handle the return value of asynchronous operations, why should they be changed to Async functions?You can try http://fibjs.org/docs/manual/... and convert it directly to synchronization
I have to say that I stared at the screen and made many drafts, but in the end I failed.
I can’t think of any way to block the current function in js but still execute the resolve of the promise in time. The idea of failure is as follows
The problem is that although
while(c_result===null && n++<100){}
blocks the function c_sync, it also blocks the execution of the.then
callback. Due to the single-threaded asynchronous mechanism, When a certain callback is triggered, if the thread is busy, the callback cannot jump into the queue. As a result, c_result cannot be assigned to the variable m during the execution of the loop. Therefore, there is no way to exit the loop.But I think this question is very interesting. I found a related article. The author solved the problem of local blocking through an external binary library.
http://blog.csdn.net/xingqili...
My understanding is:
Based on the event loop of the js engine itself, we cannot block a certain block. Because for the js code, the engine's event loop is at the bottom. But for external binary modules, it can block itself, And ensure that the event loop of the js engine completely traverses the event queue every time----to ensure that new events in the js engine can be processed during its own blocking period.
Let a() output promise can indeed solve the problem I mentioned
But when I actually modified the code, I found that the structure of most of the code was not like my problem above
but the newly added structure below
With all due respect, you do not have a deep understanding of the event loop mechanism and event core module of node.js.
promise and aysnc/await are indeed the mainstream in handling asynchronous process control today, but it does not mean that it cannot be done without them. Such simple problems can be handled back to the event method.