在我的console.log(info)
中,我希望得到"结果"的值。但是当我使用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
。我该怎么办?
由于
答案 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版本中支持该语法,请参阅:
在您没有async
和await
原生支持的地方,您可以使用Babel:
或略有不同的语法基于生成器的方法,如co
或Bluebird协同程序: