jq有同步吗?

时间:2019-06-05 21:26:11

标签: javascript node.js json promise jq

jq.run('.', '/path/to/file.json').then(console.log)是异步的,因此当我尝试使用它时,得到以下信息:Promise { <pending> }然后得到了结果,但是为时已晚...那么如何解决这个问题? 我尝试等待await,但是我不知道该放在哪里。所以这是我的代码:

const jq = require('node-jq')
const filter = '[.root[].A[].AT]'
const jsonPath = './simple.json'

 data = jq.run(filter, jsonPath).then((output) => {
    console.log(output)
  }).catch((err) => {
    console.error(err)
  })

fs.appendFile('./jqTest.txt', data + "\r\n", function (err) {
  if (err) throw err;
  console.log("complete!")
});

1 个答案:

答案 0 :(得分:1)

异步API的全部要点是您不能编写

data = getResultsAsynchronously();
doStuffWith(data);
...

(除非您使用await,这有点神奇。)

相反,传统的异步API在结果准备好时会调用一个函数:

getResultsAsynchronously(function (data) {
    doStuffWith(data);
    ...
});

即而是将同步版本中原始函数调用之后的所有代码放入回调函数中,并传递给getResultsAsynchronously

Promise仍然遵循此一般模式,但是让您将启动异步操作本身与决定如何处理结果分离开来。也就是说,您可以首先在第二步中启动异步操作,然后注册一个回调,以便稍后处理结果:

promise = getResultsAsynchronously();
// and later:
promise.then(function (data) {
    doStuffWith(data);
    ...
});

但是,如果您不想这样做,则不必将两个步骤分开:

getResultsAsynchronously().then(function (data) {
    doStuffWith(data);
    ...
});

.then还返回一个promise,您可以通过调用.then.catch附加附加的回调。

在您的代码中,

data = jq.run(filter, jsonPath).then(...).catch(...)

data只是另一个承诺,但其中没有任何有用的返回值(因为您的thencatch回调不返回任何值)。

要修正您的逻辑,它应如下所示:

jq.run(filter, jsonPath).then((data) => {
    fs.appendFile('./jqTest.txt', data + "\r\n", (err) => {
        if (err) throw err;
        console.log("complete!")
    });
}).catch((err) => {
    console.error(err)
});

回顾一下:异步结果仅在回调函数中可用。您不能像同步操作一样使用返回值。

也就是说,async / await使您可以将异步代码转换为同步代码(或至少看起来是同步的代码)。但是,此技巧仅在“内部”起作用:外部接口仍是异步的,您可以在内部编写更普通的代码。

例如:

// await is only available inside async functions, so let's define one:
(async function () {

    // magic happens here:
    let data = await jq.run(filter, jsonPath);

    fs.appendFile('./jqTest.txt', data + "\r\n", (err) => {
        if (err) throw err;
        console.log("complete!")
    });

})();  // ... and invoke it immediately

在内部,JavaScript会重写

x = await f();
doStuffWith(x);
...

变成看起来像

的东西
return f().then((x) => {
    doStuffWith(x);
    ...
});

await使您可以将回调函数的内容提取为直线代码。最终,整个async函数仍然返回一个promise。