【问题标题】:I need to return a value from a asynchronous code, but I just get the Promise object in { pending } status [duplicate]我需要从异步代码中返回一个值,但我只是在 {pending} 状态中获取 Promise 对象 [重复]
【发布时间】:2021-04-19 21:04:28
【问题描述】:

拜托,我知道这个问题之前已经回答过了。我已经阅读了this answerthis article,但我还不知道如何修复我的代码。

我创建了一个function 来读取一些文件的内容和returns 一个new Promise。这是function

// array of string representing each file's path
const allSpecFiles = [
  '/path/to/the/file1.spec.js',
  '/path/to/the/file2.spec.js',
  '/path/to/the/file3.spec.js'
];

// method to read an individual file content & return a Promise
const readFileContent = file => {
  return new Promise((resolve, reject) => {
    fs.readFile(file, 'utf8', (err, data) => {
      if (err) return reject(err);
      return resolve(data);
    });
  });
};

现在,我正在尝试循环通过 stringsarray 存储每个文件的 path,调用 readFileContent() 方法并将当前循环的值作为其 parammap() 方法传递,因为我想要使用每个文件的内容创建另一个 arraystrings

这是我尝试过的:

const allSpecFilesArr = allSpecFiles.map(async file => await readFileContent(file));
console.log(allSpecFilesArr); // I get Promise { <pending> }

我也试过像这样包装整个script

(async () => {
  const allSpecFilesArr = await allSpecFiles.map(file => readFileContent(file));
  console.log(allSpecFilesArr); // still prints Promise { <pending> }
})();

我做错了什么?

【问题讨论】:

  • 使用 Promise.all(allSpecFilesArr)
  • 得打电话给Promise.all(allSpecFilesArr).then(...)

标签: javascript node.js async-await es6-promise


【解决方案1】:

你想要的是使用Promise.all(allSpecFilesArr),因为那是一组承诺。您可以等待它,您将收到从内部已解析承诺返回的一组数据。

const fileContents = await Promise.all(allSpecFilesArr);

【讨论】:

    【解决方案2】:

    无需包装fs.readFile,使用fs/promises。试试这个:

    const fs = require('fs/promises')
    const paths = [ './one', './two' ]
    ;(async () => {
      const contents = await Promise.all(paths.map((p) => fs.readFile(p, 'utf8')))
      console.log(contents)
    })()
    

    【讨论】:

      【解决方案3】:

      第二种解决方案是部分正确的。你是 awaiting map 函数的结果,在本例中,它是一个 promise 数组。

      如果您在 map 调用前删除 await 并调用 await Promise.all(allSpecFilesArr),您将得到您需要的。

      你可以这样做:

      async read (paths) {
       const promises = [];
       for (path in paths) {
         promises.push(readFileContent(path));
       }
      
       
       const arrOfContentYouWant = await Promise.all(promises);
       return arrOfContentYouWant;
      }
      

      【讨论】:

      • 这不正确,你可以将异步函数传递给map,你只需要期望你会得到一个 Promise 数组。您可以使用Promise.all([1,2,3].map(async (x) =&gt; x)).then(console.log) 之类的内容轻松地进行测试。在一系列承诺中也没有 all 方法,我想你的意思是 Promise.all
      • @ZacAnger,感谢您指出错字,我编辑了它。对于地图部分,你是完全正确的,我的意思是没有 Promise.all 我们不能将异步函数与地图等函数一起使用,因为同步代码不会坐下来等待你的异步代码解析,而是会着火功能并继续前进。我将删除这一段以避免任何混淆。有关使用带有承诺的地图的更多信息stackoverflow.com/questions/55225272/…
      猜你喜欢
      • 1970-01-01
      • 2019-02-06
      • 2018-07-14
      相关资源
      最近更新 更多