我正在查看Angular文档中$q的例子,但我认为这可能适用于一般的承诺。下面的例子是从他们的文档中逐字复制的,包括他们的评论:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

我不清楚这是怎么回事。如果我可以对第一个.then()的结果调用.then(),将它们链接起来,我知道我可以,那么promiseB是一个promise对象,类型为object。它不是一个数字。那么“它的值将是承诺a加1的结果”是什么意思呢?

我应该像承诺的那样访问吗?。价值或类似的东西?如何成功回调返回承诺和返回“结果+ 1”?我遗漏了一些东西。


当前回答

当在交互式提示符下进行实验时,可以通过在"then()"函数中将值赋给全局变量来访问Promise的值,例如:

> promise = new Promise((resolve, reject) => resolve(17));
Promise {
   17,
   [Symbol(async_id_symbol)]: 7600,
   [Symbol(trigger_async_id_symbol)]: 5,
   [Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
   <pending>,
  [Symbol(async_id_symbol)]: 7875,
  [Symbol(trigger_async_id_symbol)]: 7600,
  [Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17

在代码中,这种想法似乎总是迫使人们将“跟进”代码放入“then()”部分(或者,等效地,如果我理解的话,放入async/await模式,如果我理解的话,它再次被重写为“then()”模式)。我想这个想法是为了防止“阻塞”系统,尽管在我看来不提供同步获取值的后门对语言设计者来说太家长式了。

注意,还是从交互式命令行:

> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null

这是因为“then()”中的代码还没有运行。

然而,在“下一行”(在交互提示符处),你可以这样做:

> xyz
17

其他回答

您可以使用JavaScript中的异步等待方法轻松做到这一点。

下面是一个使用超时检索WebRTC承诺值的示例。

function await_getipv4(timeout = 1000) { var t1 = new Date(); while(!window.ipv4) { var stop = new Date() - t1 >= timeout; if(stop) { console.error('timeout exceeded for await_getipv4.'); return false; } } return window.ipv4; } function async_getipv4() { var ipv4 = null; var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}}) findIP.then(ip => window.ipv4 = ip); return await_getipv4(); };

我觉得这个例子不言自明。注意await是如何等待结果的,所以你错过了Promise的返回。

cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}

当在交互式提示符下进行实验时,可以通过在"then()"函数中将值赋给全局变量来访问Promise的值,例如:

> promise = new Promise((resolve, reject) => resolve(17));
Promise {
   17,
   [Symbol(async_id_symbol)]: 7600,
   [Symbol(trigger_async_id_symbol)]: 5,
   [Symbol(destroyed)]: { destroyed: false }
}
> global_cheat = null;
null
> promise.then((v) => { global_cheat = v; } );
Promise {
   <pending>,
  [Symbol(async_id_symbol)]: 7875,
  [Symbol(trigger_async_id_symbol)]: 7600,
  [Symbol(destroyed)]: { destroyed: false }
}
> global_cheat
17

在代码中,这种想法似乎总是迫使人们将“跟进”代码放入“then()”部分(或者,等效地,如果我理解的话,放入async/await模式,如果我理解的话,它再次被重写为“then()”模式)。我想这个想法是为了防止“阻塞”系统,尽管在我看来不提供同步获取值的后门对语言设计者来说太家长式了。

注意,还是从交互式命令行:

> xyz=null; promise.then((v) => {xyz = v;}); console.log(`xyz=${xyz}`);
xyz=null

这是因为“then()”中的代码还没有运行。

然而,在“下一行”(在交互提示符处),你可以这样做:

> xyz
17

我学习JavaScript的速度很慢。默认情况下,所有异步函数都返回一个promise,你可以将结果包装为:

(async () => {
//Optional "await"
  await yourAsyncFunctionOrPromise()
    .then(function (result) {
      return result +1;
    })
    .catch(function (error) {
      return error;
    })()
})

从等待(MDN):

await表达式导致异步函数的执行暂停,直到Promise被解决(即,实现或拒绝),并在实现后恢复异步函数的执行。当恢复时,await表达式的值是已实现的Promise的值。 如果Promise被拒绝,await表达式抛出被拒绝的值

在MDN网络文档中阅读更多关于等待和承诺的信息。

这里有一些很好的之前的答案,这里是ES6箭头函数版本:

var something = async() => {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}