javascript route.js文件上的异步函数|节点

2fjabf4q  于 2023-01-01  发布在  Java
关注(0)|答案(2)|浏览(139)

我有一个应用程序,它有nodejs作为后端,还有一些Python脚本
问题是将“PythonShell”(访问脚本的函数)作为异步函数。我不知道为什么,但它不起作用。
我将把代码从我的router.js文件,并在它里面我把三个'console.log(' steps ')'检查序列。
应该是Step 01〉Step 02〉Step 03,但由于它不工作,它总是打印Step 01〉Step 03〉Step 02
一切都工作正常,除了这个异步问题!对我来说,它应该像现在这样工作。
如何编辑我的函数,使其先执行“goToscript/PythonShell”,然后再执行“res.json(responseScript)”?
谢啦,谢啦

router.put("/uploads/script-03", async (req, res) => {

    let options = {
        scriptPath: "scripts",
        args: JSON.stringify(req.body)
    };

    const goToScript = async () => {
        
        await PythonShell.run("script-01.py", options, (err, res) => {
            if (err) {
            }
            if (res) {
                responseScript = JSON.parse(res)
                console.log('Step 02')
            }
        });
    }

    console.log('Step 01')

    goToScript()
    
    console.log('Step 03')
    
    res.json(responseScript)
});

module.exports = router
db2dz4w8

db2dz4w81#

几件事:

    • 1.您的goToScript实际上不是异步的/返回承诺**

据我所知,PythonShell不支持异步,只支持回调,所以可以这样重写gotToScript

const goToScript = () => {
  return new Promise((resolve, reject) => {
    PythonShell.run("script-01.py", options, (err, res) => {
      if (err) {
        reject(err)
      }

      if (res) {
        responseScript = JSON.parse(res)
        console.log('Step 02')

        resolve(responseScript)
      }
    })
  })
}

const scriptResult = await goToScript()

这段代码的工作方式类似于一个常规的async函数,其中promise将解析为解析后的JSON,如果符合,则拒绝并显示错误。

    • 2.您不能将呼叫await转接到goToScript**

当你想进行一个异步调用,并与其他所有操作按顺序完成时,你需要await它。
在第一段代码中,waitFn在记录"步骤2!"之前等待了100ms:

const waitFn = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Step 2!')
      resolve()
    }, 100)
  })
}

console.log('Step 1!')
waitFn()
console.log('Step 3!')

因为你没有awaitPromise的结果,你的代码并不关心它还没有完成,并将打印:

Step 1!
Step 3!
Step 2!

但是,如果您对waitFn中返回的Promise的结果执行await,它将按顺序执行:

const waitFn = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Step 2!')
      resolve()
    }, 100)
  })
}

console.log('Step 1!')
await waitFn() // Finishes before moving on
console.log('Step 3!')

你可以阅读更多关于承诺和async/await here的内容:)

ffscu2ro

ffscu2ro2#

为了能够执行await函数-此函数需要返回一个promise。在npm page of your lib中有一个关于PythonShell.run返回内容的描述。它不返回承诺。因此它是异步的,但不是可等待的,它基于callback
所有你需要做的-promisify这个函数。另外-你需要await调用goToScript();

router.put("/uploads/script-03", async (req, res) => {
  let options = {
    scriptPath: "scripts",
    args: JSON.stringify(req.body)
  };

  const goToScript = async () => {
    return new Promise((resolve, reject) => {
      PythonShell.run("script-01.py", options, (err, res) => {
        console.log("Step 02");
        if (err) return reject(err);
        return resolve(JSON.parse(res));
      });
    });
  };

  console.log("Step 01");
  const responseScript = await goToScript();
  
  console.log("Step 03");
  res.json(responseScript);
});

module.exports = router;

相关问题