2017-10-13 19 views
0

約束が新しくなりました。 私はこのshopIdsの配列がありますPromises.allに追加の値を指定してください

let shopIdsArray = ['shop1','shop2','shop3']; 

getProducts(shopId, 'products') //promise returns the products of this shop 

残念ながら、外部の約束のコールを、shopId、単に製品を返さない約束ので、私は何とかshopIdを維持する必要がありますし、約束が終わったらそれを製品と一緒に保管してください。 私の現在のアプローチは、各shopIdとの約束を呼び出して、このようなshopsAndProductsArrayに各約束呼び出しの結果を追加することです:

shopsAndProductsArray.push({ 
    "id":shopId, 
    "products":products 
}); 

その後、私の「ラッパーの約束は」完成shopsAndProductsArrayを返す必要があります。

私の現在のコードは、(ノードが、ES6)は次のようになります。解決には

updateProducts = new Promise(

    function (resolve, reject) { 
     let shopIdsArray = ['shop1','shop2','shop3']; 
     const shopsAndProductsArray = []; 
     let promisesArray = []; 

     shopIdsArray.forEach((shopId) => { 
      let promise = getProducts(shopId, 'products') 
        .then((products) => { 
         const shopInfoObject = { 
           "id":shopId, 
           "products":products 
         }; 
         console.log("sio: ",shopInfoObject); //prints shopIds and products fine. 
         shopsAndProductsArray.push(shopInfoObject); 
         promisesArray.push(promise); 
        }); 

     }); 

     Promise.all(promisesArray) 
      .then(function (shopsAndProductsArray) { 
       resolve(shopsAndProductsArray); //the shopsAndProductsArray is undefined? 
      }); 
    } 
); 

、shopsAndProductsArrayが...空ではありませんが、shopIdsArrayとして同じ数のエントリで構成されていますが、配列の項目は未定義です。おそらく私は約束事を配列に入れてからPromise.allで作業しなければならないかもしれませんが、その時点で私は約束を所持している店のIDを失いました。

私は反復と約束について多くの他の例を読んで、他の多くの方法を試みましたが、どの点で何が呼び出されているかを完全に理解していないようです。私は確かに私がやっているやり方が間違っている約束を満たしていますが、私はPromise.allを呼び出す方法が分かりませんでした。

は、私は私が私の質問を絞り込むことができると思う:

  1. どのように私は それぞれとの約束を呼び出し、shopIdsを反復処理する必要がありますか?
  2. プロミスが商品リストを返すと、私はどのように店を保存できますか?
  3. shopIdsのすべての処理が完了したら、shopIdsと商品の配列を返すにはどうすればよいですか?

ご協力いただきありがとうございます。

編集: ありがとう、justelouise、Felix Kling。私は事を過度に複製しているのを知っていましたが、どこにでも私の指を置くことはできませんでした。私はあなたの例のおかげで、今私が行方不明だったことを理解しています。 あなたの答えは本質的に同等で、両方とも完全に説明されていると思います。私はjustelouiseに受け入れのチェックマークを付けます。なぜなら彼女は最初のようで、Felix KlingはO_oという若干の評判を持っているからです。

+0

あなたはshopsAndProductsArray.push(exchangeInfoObject) '呼び出している;'しかし、あなたが作成したオブジェクトがshopInfoObject' 'に割り当てられます。 –

+0

すべてのあなたの約束はundefined' 'に解決 - あなたの' .thenので(製品は=> '' shopsAndProductsArray'が未定義 '関数(shopsAndProductsArrayの配列である理由である何...を返しません)' –

+0

注:あなたの 'のconst shopsAndProductsArray = []; 'によって何 –

答えて

1

私はあなたのようなあなたの機能を簡素化することができると思います。

return Promise.all(shopIdsArray.map(shopId => { 
    return getProducts(shopId).then((products) => { 
    return { 
     id: shopId, 
     products, 
    }; 
    }); 
})); 

Promise.allはあなたがgetProductsで呼び出しがあるマップ機能を経由して、アレイを通して反復されているとして作成された約束の配列を返します。店舗IDごとに実行されます。製品データが返されると、あなたはまだそれに対応する店舗IDとアクセス権を持っているとidからなる新しいオブジェクトと結果を返す

return { 
    id: shopId, 
    products, 
}; 
最後には、Promise.allがために返された値を含む配列を返します

各約束はそれの中で実行される。あなたのコードは、に多くを簡素化することができる

1

updateProducts = Promise.all(
    ['shop1','shop2','shop3'].map(
    id => getProducts(id, 'products').then(products => ({id, products})) 
) 
); 

それはちょうどそれほど冗長、あなたと全く同じアプローチです。

Promise.allは既に約束を返しているので、約new Promise(...)を置く必要はありません。

あなたが何か他のものへの配列の各要素を変換したい場合は、Array#mapは、より有用な方法です。渡されたコールバックを配列のすべての要素に適用し、その戻り値の配列を返します。あなたのケースでは、ショップIDごとにプロミスを作成したいと思っています。それは何ですか

['shop1','shop2','shop3'].map(id => getProducts(id, 'products')) 

です。あなただけの製品だけでなく、IDを取得する必要はありませんので、

は今、私たちは

.then(products => ({id, products})) 

が何をするかであるgetProducts少し、結果を変更する必要があります。これに関して本当に特別なことは何もありません。 products配列の代わりに、idproductsという2つのプロパティを持つオブジェクトを返すだけです。 Promise.allとして

Array#mapあなたが「手動」の約束(promisesArray)と結果(shopsAndProductsArray)を追跡する必要はありません。

関連する問題