如何获取承诺的价值?

时间:2015-04-08 13:42:54

标签: javascript angularjs promise angular-promise

我正在看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是一个类型为Object的承诺对象。它不是Number。那么他们的意思是“它的价值将是promiseA增加1的结果”?

我应该以{{1​​}}或类似的方式访问它吗?成功回调如何返回一个承诺并返回“结果+ 1”?我错过了什么。

12 个答案:

答案 0 :(得分:86)

promiseA的{​​{1}}函数返回一个新的承诺(then),在promiseB解析后立即解析,其值是返回的值来自promiseA内的成功函数。

在这种情况下,使用值promiseA解析promiseA,然后立即使用值result解析promiseB

访问result + 1的值与访问promiseB的结果的方式相同。

promiseA

答案 1 :(得分:17)

当承诺被解决/拒绝时,它将调用其成功/错误处理程序:

var promiseB = promiseA.then(function(result) {
   // do something with result
});

then方法还返回一个promise:promiseB,它将被解析/拒绝,具体取决于来自promiseA 的成功/错误处理程序的返回值。

promiseA的成功/错误处理程序可以返回三个可能的值,这将影响promiseB的结果:

1. Return nothing --> PromiseB is resolved immediately, 
   and undefined is passed to the success handler of promiseB
2. Return a value --> PromiseB is resolved immediately,
   and the value is passed to the success handler of promiseB
3. Return a promise --> When resolved, promiseB will be resolved. 
   When rejected, promiseB will be rejected. The value passed to
   the promiseB's then handler will be the result of the promise

有了这种理解,您可以理解以下内容:

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

then调用立即返回promiseB。 当promiseA解决后,它会将结果传递给promiseA的成功处理程序。 由于返回值是promiseA的结果+ 1,成功处理程序返回一个值(上面的选项2),因此promiseB将立即解决,并且promiseB的成功处理程序将通过promiseA' s的结果+ 1。

答案 2 :(得分:2)

promiseB的

.then函数接收从promiseA的.then函数返回的内容。

这里promiseA返回的是一个数字,它将在promiseB的成功函数中以number参数的形式提供。然后将增加1

答案 3 :(得分:2)

解析评论与您目前的理解有所不同可能会有所帮助:

// promiseB will be resolved immediately after promiseA is resolved

这表明promiseB是一个承诺,但会在promiseA解决后立即解决。查看此方法的另一种方式意味着promiseA.then()会返回分配给promiseB的承诺。

// and its value will be the result of promiseA incremented by 1

这意味着promiseA解析为的值是promiseB将作为successCallback值接收的值:

promiseB.then(function (val) {
  // val is now promiseA's result + 1
});

答案 4 :(得分:0)

promiseA(pram).then(
     result => { 
     //make sure promiseA function allready success and response
     //do something here
}).catch(err => console.log(err)) => {
     // handle error with try catch
}

答案 5 :(得分:0)

您可以使用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();
};

答案 6 :(得分:0)

pixelbits答案是正确的,您应该始终使用.then()访问生产代码中的promise值。

但是,有一种方法可以通过使用以下不受支持的内部node.js绑定来直接访问承诺的值:

process.binding('util').getPromiseDetails(myPromise)[1]

警告:process.binding从未打算在nodejs核心之外使用,nodejs核心团队正在积极寻求弃用它

https://github.com/nodejs/node/pull/22004 https://github.com/nodejs/node/issues/22064

答案 7 :(得分:0)

这个例子我很容易理解。请注意,等待如何等待结果,所以您错过了返回的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}

答案 8 :(得分:0)

在Node REPL中,为了获得作为Promise价值的数据库连接,我采用了以下方法:

let connection
try {
  (async () => {
    connection = await returnsAPromiseResolvingToConnection()
  })()
} catch(err) {
  console.log(err)
}

带有await的行通常会返回一个承诺。可以将此代码粘贴到Node REPL中,或者如果保存在index.js中,则可以使用

在Bash中运行
node -i -e "$(< index.js)"

在运行具有对set变量访问权限的脚本后,将您留在Node REPL中。要确认异步函数已返回,您可以例如登录connection,然后就可以使用该变量了。当然,对于异步函数之外的脚本中的任何代码,当然都不希望依靠正在解析的异步函数。

答案 9 :(得分:0)

上面有一些很好的答案,这是ES6 Arrow函数版本

node: 4

答案 10 :(得分:0)

我对javascript Promise学习很慢,默认情况下,所有异步函数都会返回Promise,您可以将结果包装为:

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

等待表达式使async函数的执行暂停,直到Promise被解决(即实现或拒绝),并在实现之后恢复异步函数的执行。恢复后,等待表达式的值是已兑现的诺言的承诺。 如果Promise被拒绝,则await表达式将抛出被拒绝的值。”

await网络文档中详细了解promisesMDN

答案 11 :(得分:-3)

也许这个小的Typescript代码示例会有所帮助。

private getAccount(id: Id) : Account {
    let account = Account.empty();
    this.repository.get(id)
        .then(res => account = res)
        .catch(e => Notices.results(e));
    return account;
}

此处repository.get(id)返回Promise<Account>。我将其分配给account语句中的变量then