我无法获得"结果"的价值。在Node.js中

时间:2017-05-02 21:32:31

标签: javascript node.js es6-promise

在我的console.log(info)中,我希望得到&#34;结果&#34;的值。但是当我使用console.log(info)时,我会得到Promise { <pending> }

var info=new Promise((resolve, reject) => {
  request(options, (err, res, body) => {
    if (body.match('success') || body.match('code="25"')) {
      resolve("success");
    } else {
      reject(body);
    }
  });
}).then(result => {           
  return result;
}).catch(err => {
  console.log("error: " + err)
});

console.log(info);

我想获得info == result。我该怎么办?

由于

2 个答案:

答案 0 :(得分:4)

在您的代码中,info是一个承诺。因此,您不会将info与任何内容进行比较。要在promise中访问结果,请在promise上使用.then(),如下所示:

info.then(result => {
    // test result here
}).catch(err => {
    // handle error here
});

此外,您的.catch()处理程序在记录后会“误食”错误。如果您不重新抛出错误或从.catch()处理程序返回被拒绝的承诺,则该错误将被视为“已处理”且承诺状态将更改为已完成。

所以,你可以这样做:

let info = new Promise((resolve, reject) => {

    request(options, (err, res, body) => {
        if (body.match('success') || body.match('code="25"')) {
            resolve("success");
        } else {
            reject(body);
        }
    });
}).catch(err => {
    console.log("error: " + err);
    // rethrow error so promise stays rejected
    throw err;
});

info.then(result => {
    // test result here
}).catch(err => {
    // handle error here
});

答案 1 :(得分:3)

这里发生了什么

首先解释一下这里发生了什么。当你做这样的事情时:

var info = new Promise((resolve, reject) => {
  // ...
}).then(result => {
  // ...
}).catch(err => {
  // ...
});

然后最终因为info变量的值是一个承诺。这是因为你从new Promise()构造函数返回的promise开始,你调用它返回第二个promise的.then()方法,然后在第二个promise上调用.catch()方法返回第三个承诺 - 第三个承诺是保存到info变量中的内容。

所有这些方法调用都会在原始HTTP请求完成之前立即返回,因此当您到达下一行时:

console.log(info);

无法从request()电话中获取响应的值,因为它尚未发生(request()回调尚未被调用这点)。 info变量具有promise,该promise是一个对象,可用于注册在值最终可用时运行的回调。当您将其传递给console.log()时,它会打印出它的承诺。

如何获取值

现在,当您希望在最终可用时打印该值时,您可以将承诺解析回调附加到您拥有的承诺上。用这样的代码:

info.then((value) => {
  // you can use the value here
  console.log('Value:', value);
}).catch((err) => {
  // the promise got rejected
  console.log('Error:', err);
});

如果您使用的是相对较新版本的Node(7.0+),那么如果您在使用await关键字声明的函数内部,则可以使用async来获取分辨率值承诺这样:

(async function () {

  let value = await info;
  console.log(value);

})();

或更短:

(async () => {

  console.log(await info);

})();

(如果您已经在async功能内,那么您就不需要(async () => { ... })();包装。)

如何运作

await关键字的作用是从隐式生成器函数中获取承诺,该函数将控制传递给外部协程控制代码,该代码将解析和拒绝处理程序附加到该产生的承诺并再次启动生成器如果承诺被拒绝,则从await运算符返回已解析的值或引发异常。然后,生成器可以继续使用返回值并捕获异常,或者它可以让异常冒泡到外部块,在那里它可以被捕获或转换为拒绝async函数返回的隐式承诺,如果不是一路走来。

如何使用

这可能看起来很复杂,但从代码的角度来看,它可以让你做以下事情:

let value = await fun();

(其中fun()是一个返回promise的函数),并且value变量中具有已解析的promise值(实际值,而不是promise)。

请记住,当有关的承诺被拒绝时,await关键字会引发异常。要处理这种情况,您可以使用try / catch块:

try {
  let value = await fun();
  // promise got resolved, you have value here:
  console.log('Value:', value);
} catch (error) {
  // promise got rejected, you have error here:
  console.log('Error:', error);
}

这相当于没有新语法的代码:

fun().then((value) => {
  // promise got resolved, you have value here:
  console.log('Value:', value);
}).catch((error) => {
  // promise got rejected, you have error here:
  console.log('Error:', error);
});

主要区别在于await在单个try块中的多个promise上的变量作用域,而不是使用多个链式.then()处理程序,每个都返回一个新的promise。 / p>

您的代码看起来像await,但它没有

我添加了如何使用await修复代码的示例,因为您编写了代码,如下所示:

var info = new Promise(...);
// here the 'info' variable is set to a promise

真的是这样的:

var info = await new Promise(...);
// here the 'info' variable is set to the value
// that the promise eventually resolves to

更多信息

有关详细信息,请参阅:

节点支持

要在Node版本中支持该语法,请参阅:

在您没有asyncawait原生支持的地方,您可以使用Babel:

或略有不同的语法基于生成器的方法,如co或Bluebird协同程序: