Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 创建异步函数以稍后在express route中调用结果_Javascript_Express_Async Await - Fatal编程技术网

Javascript 创建异步函数以稍后在express route中调用结果

Javascript 创建异步函数以稍后在express route中调用结果,javascript,express,async-await,Javascript,Express,Async Await,我必须通过API从Box.com获取一个Excel文件,并将Excel转换为JSON。稍后将使用Express和Handlebar呈现此JSON 我创建了以下函数来获取Excel/JSON: let getExternalFile = async () => { const stream = await client.files.getReadStream('123456789'); const external = await fs.createWriteStream('/ext

我必须通过API从Box.com获取一个Excel文件,并将Excel转换为JSON。稍后将使用Express和Handlebar呈现此JSON

我创建了以下函数来获取Excel/JSON:

let getExternalFile = async () => {
  const stream = await client.files.getReadStream('123456789');
  const external = await fs.createWriteStream('/external.xlsx');
  stream.pipe(external);
  let finished = await external.on('finish', async () => {
    const excel = await excelToJson({
      source: fs.readFileSync(external.path),
      header: {
        rows: 1
      },
      columnToKey: {
        A: "edate",
        B: "esource"
      },
      sheets: ['Sheet1']
    });
    console.log(excel);
    return excel
  })
}
我现在的问题是,当我这样做时,我不知道如何解决悬而未决的承诺:

let testData = getExternalFile();
console.log(testData); // Promise { <pending> }

我必须用匿名异步函数来调用它吗?

async
/
wait
并不是所有异步事物的灵丹妙药。他们被设计成只履行承诺。具体来说,
async
/
await
不适用于事件发射器。
getExternalFile
的正确实现应该是:

let getExternalFile = async () => {
  const stream = client.files.getReadStream('123456789'); // no await here
  const external = fs.createWriteStream('/external.xlsx'); // no await here
  stream.pipe(external);

  let finished = new Promise ((resolve, reject) => {
    external.on('finish', async () => { // cannot use await here
      const excel = await excelToJson({
        source: fs.readFileSync(external.path),
        header: {
          rows: 1
        },
        columnToKey: {
          A: "edate",
          B: "esource"
        },
        sheets: ['Sheet1']
      });
      console.log(excel);

      resolve(excel);
    })
  });

  return finished; // return the promise so you can await it later
}
所有非承诺函数(我不会称它们为非“异步”,因为它会混淆异步函数和非异步函数之间的区别,因为人们有时使用“异步”表示异步,有时表示“异步”关键字,这是承诺生成函数)。。。我离题了。。。所有非承诺函数都不能与
wait
一起使用。这包括事件发射器
x.on('some_event'…)

对于这种情况,您需要将它们包装在
newpromise()
中,以将它们转换为承诺

现在我们已经编写了上述函数,我们可以简单地等待结果:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testData = await getExternalFile(); // use await here!!

    // ...
});
app.get('/',async/*{
让testData=await getExternalFile();//在此处使用await!!
// ...
});
如果有多个等待,则功能可能较慢:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testData = await getExternalFile();
    let testData2 = await getExternalFile2(); // SLOW!

    // ...
});
app.get('/',async/*{
让testData=等待getExternalFile();
让testData2=等待getExternalFile2();//慢!
// ...
});
如果您能顺利完成,您可以并行执行异步函数:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testDataArray = await Promise.all([
        getExternalFile(), getExternalFile2()  // FAST!
    ]);

    // ...
});
app.get('/',async/*{
让testDataArray=wait Promise.all([
getExternalFile(),getExternalFile2()//快!
]);
// ...
});

Epologue:错误 在实际代码中,您应该捕获等待的代码上的错误,以防止服务器崩溃:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    try {
        let testData = await getExternalFile(); // use await here!!

        // ...
    }
    catch (err) {

        // ...
    }
});
app.get('/',async/*{
试一试{
让testData=await getExternalFile();//在此处使用await!!
// ...
}
捕捉(错误){
// ...
}
});

或者,您也可以使用中间件(如)来捕获异步错误。

异步
/
等待
并不是解决所有异步问题的灵丹妙药。他们被设计成只履行承诺。具体来说,
async
/
await
不适用于事件发射器。
getExternalFile
的正确实现应该是:

let getExternalFile = async () => {
  const stream = client.files.getReadStream('123456789'); // no await here
  const external = fs.createWriteStream('/external.xlsx'); // no await here
  stream.pipe(external);

  let finished = new Promise ((resolve, reject) => {
    external.on('finish', async () => { // cannot use await here
      const excel = await excelToJson({
        source: fs.readFileSync(external.path),
        header: {
          rows: 1
        },
        columnToKey: {
          A: "edate",
          B: "esource"
        },
        sheets: ['Sheet1']
      });
      console.log(excel);

      resolve(excel);
    })
  });

  return finished; // return the promise so you can await it later
}
所有非承诺函数(我不会称它们为非“异步”,因为它会混淆异步函数和非异步函数之间的区别,因为人们有时使用“异步”表示异步,有时表示“异步”关键字,这是承诺生成函数)。。。我离题了。。。所有非承诺函数都不能与
wait
一起使用。这包括事件发射器
x.on('some_event'…)

对于这种情况,您需要将它们包装在
newpromise()
中,以将它们转换为承诺

现在我们已经编写了上述函数,我们可以简单地等待结果:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testData = await getExternalFile(); // use await here!!

    // ...
});
app.get('/',async/*{
让testData=await getExternalFile();//在此处使用await!!
// ...
});
如果有多个等待,则功能可能较慢:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testData = await getExternalFile();
    let testData2 = await getExternalFile2(); // SLOW!

    // ...
});
app.get('/',async/*{
让testData=等待getExternalFile();
让testData2=等待getExternalFile2();//慢!
// ...
});
如果您能顺利完成,您可以并行执行异步函数:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    let testDataArray = await Promise.all([
        getExternalFile(), getExternalFile2()  // FAST!
    ]);

    // ...
});
app.get('/',async/*{
让testDataArray=wait Promise.all([
getExternalFile(),getExternalFile2()//快!
]);
// ...
});

Epologue:错误 在实际代码中,您应该捕获等待的代码上的错误,以防止服务器崩溃:

app.get('/', async /* <--IMPORTANT */ (req, res) => {
    try {
        let testData = await getExternalFile(); // use await here!!

        // ...
    }
    catch (err) {

        // ...
    }
});
app.get('/',async/*{
试一试{
让testData=await getExternalFile();//在此处使用await!!
// ...
}
捕捉(错误){
// ...
}
});

或者,您可以使用一个中间件,例如捕获异步错误。

如果它是一个返回的承诺,您不能添加
。然后()
并在那里添加您的代码吗?您已经在使用async/await,所以也要等待这个承诺
wait getExternalFile()
@mrks您没有从
getExternalFile()
返回任何内容,我认为如果您有多个承诺,可以将它们存储在一个数组中并使用
Promise.all()
等待所有问题解决。您还需要返回
finished
变量。在外部范围中定义并返回
excel
。如果是返回的承诺,您不能添加
。然后()
并在那里添加代码吗?您已经在使用async/wait,所以也要等待这个承诺
wait getExternalFile()
@mrks您没有从
getExternalFile()
返回任何内容,我认为如果您有多个承诺,可以将它们存储在一个数组中并使用
Promise.all()
等待所有问题解决。您还需要返回
finished
变量。在外部范围中定义并返回
excel
。很好!别忘了处理快速路线中的错误callbacks@ArturKhrabrov是的,我真的应该试试。。抓住积木或使用承诺抓住中间环节!别忘了处理快速路线中的错误callbacks@ArturKhrabrov是的,我真的应该试试。。捕获块或使用承诺捕获中间件