簡體   English   中英

如何在節點js中將異步轉換為同步

[英]How to convert Asynchronous to Synchronous in node js

我是nodejs的菜鳥。現在我在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"]

我已經學習並嘗試了一些關於異步到同步的方法,但我沒有成功。而且我必須在 readFile 中使用異步方法。

那么我怎樣才能得到 ["a","b","a","b","a","b"] 呢? 誰能給我一些建議?

非常感謝!

您無法將異步轉換為同步,但您可以讓 rest 實現等待異步函數完成

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 的承諾方法不可用

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);
})

以下是我編寫 function 的方法。 Since your version of Node.js doesn't have support for the 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()創建一個 promise 數組並await readFile()調用與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);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM