如何在node js中将异步转换为同步
How to convert Asynchronous to Synchronous in node js
我是nodejs.And的菜鸟,现在我在node js中遇到了一个关于异步和同步的问题。
这是我的代码:
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans (arr_a) {
var txs_arr_tmp = [];
for(let aInfo of arr_a) {
var fs = require('fs');
if (aInfo == "a") {
fs.readFile("./debug.json", function (error_file, data_file) {
if (error_file) {
console.log(error_file)
} else {
txs_arr_tmp.push("a");
}
});
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
我希望控制台会打印:
["a","b","a","b","a","b"]
但是我居然得到了:
["b","b","b"]
我已经学习并尝试了一些关于异步到同步的方法,但我没有succeed.And我必须在 readFile 中使用异步方法。
那么如何才能得到["a","b","a","b","a","b"]呢?谁能给我一些建议?
非常感谢!
你不能将异步转换为同步,但你可以让你的其余实现等待异步函数完成
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans(arr_a) {
var txs_arr_tmp = [];
for (let aInfo of arr_a) {
const fs = require('fs').promises;
if (aInfo == "a") {
try {
await fs.readFile("./debug.json")
txs_arr_tmp.push("a");
} catch (error) {
console.log(error)
var obj_addr = {
"success": false,
"error_no": 1,
"error_info": "err with addrs"
}
return res_send.jsonp(obj_addr);
}
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
如果 fs 的 promisified 方法不可用
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans(arr_a) {
var txs_arr_tmp = [];
for (let aInfo of arr_a) {
let util = require('util');
const readFile = util.promisify(require('fs').readFile);
if (aInfo == "a") {
try {
await readFile("./debug.json")
txs_arr_tmp.push("a");
} catch (error) {
console.log(error)
var obj_addr = {
"success": false,
"error_no": 1,
"error_info": "err with addrs"
}
// return res_send.jsonp(obj_addr);
}
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
以下是我编写函数的方法。由于您的 Node.js 版本不支持 fs.promises
API, you can use util.promisify()
to convert fs.readFile()
from a callback API to a promise API, then use Array.prototype.map()
to create an array of promises and await
the readFile()
calls in parallel with Promise.all()
:
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const time_begin = Date.now();
console.log("begin time:" + time_begin);
const arr_a = ['a', 'b', 'a', 'b', 'a', 'b'];
async function iterTrans (arr_a) {
// array map allows parallel asynchronicity
const txs_arr_tmp_promises = arr_a.map(async aInfo => {
// use early return (to avoid nesting large blocks inside if statements)
if (aInfo !== 'a') return 'b';
// let await throw here if file error occurs
const data_file = await readFile('./debug.json');
return 'a';
});
return Promise.all(txs_arr_tmp_promises);
}
iterTrans(arr_a).then(txs_arr_tmp => {
const content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
}).catch(error => {
// handle errors here
console.log(error);
});
我是nodejs.And的菜鸟,现在我在node js中遇到了一个关于异步和同步的问题。
这是我的代码:
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans (arr_a) {
var txs_arr_tmp = [];
for(let aInfo of arr_a) {
var fs = require('fs');
if (aInfo == "a") {
fs.readFile("./debug.json", function (error_file, data_file) {
if (error_file) {
console.log(error_file)
} else {
txs_arr_tmp.push("a");
}
});
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
我希望控制台会打印:
["a","b","a","b","a","b"]
但是我居然得到了:
["b","b","b"]
我已经学习并尝试了一些关于异步到同步的方法,但我没有succeed.And我必须在 readFile 中使用异步方法。
那么如何才能得到["a","b","a","b","a","b"]呢?谁能给我一些建议?
非常感谢!
你不能将异步转换为同步,但你可以让你的其余实现等待异步函数完成
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans(arr_a) {
var txs_arr_tmp = [];
for (let aInfo of arr_a) {
const fs = require('fs').promises;
if (aInfo == "a") {
try {
await fs.readFile("./debug.json")
txs_arr_tmp.push("a");
} catch (error) {
console.log(error)
var obj_addr = {
"success": false,
"error_no": 1,
"error_info": "err with addrs"
}
return res_send.jsonp(obj_addr);
}
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
如果 fs 的 promisified 方法不可用
var time_begin = Date.now();
console.log("begin time:" + time_begin);
arr_a = ['a', 'b', 'a', 'b', 'a', 'b']
async function iterTrans(arr_a) {
var txs_arr_tmp = [];
for (let aInfo of arr_a) {
let util = require('util');
const readFile = util.promisify(require('fs').readFile);
if (aInfo == "a") {
try {
await readFile("./debug.json")
txs_arr_tmp.push("a");
} catch (error) {
console.log(error)
var obj_addr = {
"success": false,
"error_no": 1,
"error_info": "err with addrs"
}
// return res_send.jsonp(obj_addr);
}
} else {
txs_arr_tmp.push("b");
}
}
return txs_arr_tmp;
}
iterTrans(arr_a).then((txs_arr_tmp) => {
var content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
})
以下是我编写函数的方法。由于您的 Node.js 版本不支持 fs.promises
API, you can use util.promisify()
to convert fs.readFile()
from a callback API to a promise API, then use Array.prototype.map()
to create an array of promises and await
the readFile()
calls in parallel with Promise.all()
:
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const time_begin = Date.now();
console.log("begin time:" + time_begin);
const arr_a = ['a', 'b', 'a', 'b', 'a', 'b'];
async function iterTrans (arr_a) {
// array map allows parallel asynchronicity
const txs_arr_tmp_promises = arr_a.map(async aInfo => {
// use early return (to avoid nesting large blocks inside if statements)
if (aInfo !== 'a') return 'b';
// let await throw here if file error occurs
const data_file = await readFile('./debug.json');
return 'a';
});
return Promise.all(txs_arr_tmp_promises);
}
iterTrans(arr_a).then(txs_arr_tmp => {
const content_str = JSON.stringify(txs_arr_tmp);
console.log(content_str);
}).catch(error => {
// handle errors here
console.log(error);
});