約束の価値にアクセスするには?


146

私は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です。それはではありませんNumber。では、「その値は、promiseAが1ずつ増加した結果になる」とはどういう意味ですか

私はそれにアクセスするpromiseB.valueべきですか、それともそのようなものですか?成功のコールバックはどのようにプロミスを返し、「結果+ 1」を返すことができますか?何か不足しています。




この質問は5歳で、回答は承認されています...
temporary_user_name

@temporary_user_name:昔の質問であっても、いつでも投票することができます。
halfer

回答:


141

promiseAthen関数は、promiseB解決された直後に解決される新しいpromise()を返しますpromiseA。その値は、success関数から返されたものの値ですpromiseA

この場合、promiseA値で解決される- resultと直ちに解決promiseBの値を持ちますresult + 1

の値へのpromiseBアクセスは、の結果へのアクセスと同じ方法で行われますpromiseA

promiseB.then(function(result) {
    // here you can use the result of promiseB
});

2019年12月の編集async/ awaitがJSの標準になり、上記のアプローチの代替構文を使用できるようになりました。あなたは今書くことができます:

let result = await functionThatReturnsPromiseA();
result = result + 1;

これでpromiseBはなくなりました。promiseAの結果をを使用してアンラップawaitしたので、直接操作できます。

ただし、関数await内でのみ使用できasyncます。したがって、少しズームアウトするには、上記を次のように含める必要があります。

async function doSomething() {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}

2
約束は理論的には彼ら自身のオブジェクトです。これらには、promiseの成功関数を介してアクセスできる結果が含まれています。
Nachshon Schwartz

2
したがって、promiseの非同期コールバックの戻り値を操作する場合は、別の非同期コールバック内で行う必要があります。理にかなっています。私はいくつかの究極のプリミティブな戻り値を取得する方法を探していましたが、コンテキストが与えられた場合、それは理由に逆らうと思います。
temporary_user_name

2
@Aerovistae実際には、ES6はこれを可能にするジェネレーターを導入し、ES7は非同期関数を導入します-どちらも、(バックグラウンドでステートマシンを実行することにより)同期コードのように見えるプロミスよりも構文糖質を提供します。
Benjamin Gruenbaum 2015

25

promiseが解決/拒否されると、成功/エラーハンドラーが呼び出されます。

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

このthenメソッドはpromise:promiseBも返します。promiseA の成功/エラーハンドラーからの戻り値に応じて解決/拒否されます

promiseAの成功/エラーハンドラーが返す可能性のある3つの値があり、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の結果+ 1が渡されます。


4

.thenpromiseBの関数はpromiseAの関数から返された.thenものを受け取ります。

ここでpromiseAが返す数値はpromiseBのnumber成功関数のパラメーターとして使用できます。その後、1ずつ増加します


3

現在の理解とは少し異なる方法でコメントを解析すると、役立つ場合があります。

// promiseB will be resolved immediately after promiseA is resolved

これはpromiseB約束であることを示していますが、解決後すぐにpromiseA解決されます。これの別の見方promiseA.then()は、に割り当てられているpromiseを返すことを意味しますpromiseB

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

つまり、promiseA解決された値は、promiseBsuccessCallback値として受け取る値です。

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

2

pixelbitsの答えは正しいので.then()、製品コードのpromiseの値にアクセスするには常にを使用する必要があります。

ただし、次のサポートされていない内部node.jsバインディングを使用して、解決された直後にpromiseの値にアクセスする方法があります。

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

警告:process.bindingがnodejsコアの外部で使用されることを意図したものではなく、nodejsコアチームは積極的に非推奨にする予定です。

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


1

この例は自明です。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}

これは非同期関数内にある必要があります。
サメット

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
}

1
このコードは質問に答えることがありますが、問題を解決する方法理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
アレクサンダー

0

これは、JavaScriptの非同期待機メソッドを使用して簡単に行うことができます。

以下は、タイムアウトを使用してWebRTC promise値を取得する例です。

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();
};


ここではなく、実際のブラウザでこのスニペットを実行することが重要です。これはサンドボックス化が原因であると思います。
OxFEEDFACE 2018

0

Node REPLでは、promiseの価値であるDB接続を取得するために、次のアプローチを採用しました。

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

との行awaitは通常、promiseを返します。このコードはノードREPLに貼り付けることができます。または、コードを保存するindex.jsと、Bashで実行できます。

node -i -e "$(< index.js)"

これは、設定された変数へのアクセス権を持つスクリプトを実行した後、ノードREPLに残ります。非同期関数が返されたことを確認するには、connectionたとえばログに記録して、変数を使用する準備が整います。もちろん、非同期関数の外部にあるスクリプト内のコードについては、まだ解決されていない非同期関数を当てにしたくありません。


0

上記には良い答えがいくつかあり、ここにES6 Arrow関数バージョンがあります

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

0

私はjavascript promiseの学習に時間がかかります。デフォルトでは、すべての非同期関数がpromiseを返します。結果を次のようにラップできます。

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

" await式により、非同期関数の実行は、Promiseが解決される(つまり、実行または拒否される)まで一時停止し、実行後に非同期関数の実行を再開します。再開すると、await式の値は、実行されたPromiseの値になります。 。Promiseが拒否された場合、await式は拒否された値をスローします

MDN Web Docs でawaitpromiseについて詳しく読む


-5

たぶん、この小さな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


1
あなたのコードは約束が解決される前にアカウントを返します、そしてそれがそれが反対投票された理由です、あなたのコードは常にAccount.empty();を返します。
Felype 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.