2016-11-07 54 views
1

我有一个叫做fetchMerchantData的方法,它调用3个其他的异步方法。我正在尝试使用Promise,以便在所有请求都完成但不起作用之前,它不会调用resp.direct(301, ...)节点+ ES6:如何使用Promise.all和异步请求?

function fetchOauth2Token(authorizationCode, resp) { 
    ... 
    request({ 
    url: `https://connect.squareup.com/oauth2/token`, 
    method: "POST", 
    json: true, 
    headers: oauthRequestHeaders, 
    form: oauthRequestBody, 
    }, (error, oauthResp, body) => { 
    if (body.access_token) { 
     Promise.resolve(fetchMerchantData(body.access_token, body.merchant_id)).then(() => { 
     console.log("last!"); //<--------------------- this is printing first 
     resp.redirect(
      301, 
      `myurl.com/blah` 
     ); 
     }); 
     ; 
    } else { 
     // TODO find out what to do on failure 
     resp.redirect(301, `myurl.com/?error=true`); 
    } 
    }) 
} 

function fetchMerchantData(access_token, merchant_id){ 
    const updates = {}; 
    request({ 
    url: `https://connect.squareup.com/v1/me/locations`, 
    method: "GET", 
    json: true, 
    headers: { 
     Authorization: `Bearer ${access_token}`, 
     Accept: 'application/json', 
     "Content-Type": "application/json", 
    }, 
    }, (error, response) => { 
    if (!error) { 
     const locations = response.body; 

     Promise.all([ 
     saveMerchant(merchant_id, access_token, locations), 
     saveLocations(merchant_id, locations), 
     installWebhookForLocations(access_token, locations), 
     ]).then(values => { 
     console.log("first!"); //<--------------------- this is printing last 
     return Promise.resolve("Success"); 
     }) 
    } 
    }); 
} 

而这里的saveMerchant方法,它调用火力点的例子:

function saveMerchant(merchant_id, access_token, locations) { 
    const merchantRef = database.ref('merchants').child(merchant_id); 
    const location_ids = locations.map(location => location.id); 

    merchantRef.update({ 
    access_token, 
    location_ids, 
    }); 
} 

我将如何同步呢?

== == UPDATE

这是我installWebhookForLocations方法的样子:

function installWebhookForLocations(access_token, locations){ 
    const locationIds = locations.map(location => location.id); 
    locationIds.forEach((locationId) => { 
    request({ 
     url: `https://connect.squareup.com/v1/${locationId}/webhooks`, 
     method: "PUT", 
     json: true, 
     headers: { 
     Authorization: `Bearer ${access_token}`, 
     Accept: 'application/json', 
     "Content-Type": "application/json", 
     }, 
     body: ["PAYMENT_UPDATED"], 
    }, (error) => { 
     if (!error){ 
     console.log(`Webhook installed for ${locationId}`); 
     } 
    }); 
    }); 
} 
+1

'saveMerchant'不返回任何东西? –

+0

nope它只是将它保存到firebase – Edmund

+1

我认为布赖恩的观点是,如果它没有返回任何东西..那么它不会返回一个承诺.. :)你的saveLocations&installWebhookForLocations返回承诺。? – Keith

回答

1

这里是saveMerchant的一个例子,将使用一个承诺。

function saveMerchant(merchant_id, access_token, locations) { 
    return new Promise(function (resolve, reject) { 
    const merchantRef = database.ref('merchants').child(merchant_id); 
    const location_ids = locations.map(location => location.id); 

    merchantRef.update({ 
     access_token, 
     location_ids, 
    }, function (error) { 
     if (error) return reject(error); 
     resolve(); 
    }); 
    }); 
} 

作出上述更容易,有一个名为蓝鸟一个很好的承诺库,它有一个promisify工具,你可以应用到火鸟更新方法。

同样对于你的第二个问题,你使用forEach,蓝鸟有一个很好的实用函数叫做map,你可以用它来代替。

+0

ooo我可以做同样的请求回调吗? – Edmund

+0

是的,甚至还有一个基于promise的请求库。这多做一些让请求承诺的基础,它也作为承诺处理流。 - > https://www.npmjs.com/package/request-promise基本上任何有异步方法回调的东西都可以做成承诺。 – Keith

+0

让承诺变得真的很棒的是,新的ES6特性,比如'async'和'await',可以承诺让事情更好。 – Keith