2017-01-05 23 views
5

JS API ile etkileşim kurmaya çalışıyor ancak bir Grunt görevi tarafından çalıştırıldığında başarısız oluyor; Sanırım mantığım karıştı. Benim adımlar: dosyadanBir yürütücü işlevinden bir söz döndürmek?

  • olsun belirteçleri, eski ise (check_tokens)
  • onları kontrol - yenilemek için (refresh_tokens)
  • çağrı API bunları yenilemek, başarısız olursa - yenilerini almak (authorize_with_api) < - Bu

Şu Grunt görevi birraporları authorize_with_api den

  • hatasıyla reddetmek veya jeton ile çözmek konudurve asla tamamlamaz. authorize_with_api numaralı aramayı görüştüğümde bir hatayla düzgün şekilde çıkar ve en üstteki caught error! mesajım yazdırılır.

    Neden yürütme işlevinden bir söz veremiyorum? Mantığımın nesi var? Bir söz gidermezse bir Promise yapıcısı (veya bunun içindeki herhangi bir fonksiyonu) dönen

    /* global sdk, config, tokens */ 
    return getTokens().then((p_tokens) => { 
        tokens = p_tokens; 
        return check_tokens(tokens); 
    }).then((tokens) => { 
        console.log('then() is called!'); 
    }).catch((err) => { 
        console.error('caught error!', err); 
    }); 
    
    function check_tokens(tokens) { 
        if(are_old(tokens)) { // returns true 
         return refresh_tokens(tokens); 
        } 
        return Promise.resolve(tokens); 
    } 
    
    function refresh_tokens(tokens) { 
        return new Promise(function(resolve, reject) { 
         sdk.refreshTokens(tokens.refresh_token, function(err, new_tokens) { 
          if(err) { 
           if(error.code === 'invalid_grant') { 
            return authorize_with_api(); 
           } 
           reject('refreshTokens failed'); 
          } else if(newTokens) { 
           resolve(new_tokens); 
          } 
         }); 
        }); 
    } 
    
    function authorize_with_api() { 
        return new Promise(function(resolve, reject) { 
         sdk.getTokens(config.auth_code, function(err, tokens) { 
          if(err) { 
           reject('getTokens failed'); 
          } else if(tokens) { 
           resolve(tokens); 
          } 
         }); 
        }); 
    } 
    
  • +0

    ', içeri geçmek demek istedi? Bunu çağıran görevinizi göstermek yararlı olabilir –

    +1

    Lütfen kendi promisitenizi yapmaktan kaçının. Bu görevi çözmek için kütüphaneler yazılmıştır, bunlardan birini kullanın. Örneğin, bluebird sizin için yapabilir. http://bluebirdjs.com/docs/api/promise.promisifyall.html – Tomalak

    +1

    @Tomalak Daha fazlasını açıklayabilir misiniz? OP yerli Promises kullanıyor? –

    cevap

    8

    : yerine sdk.refreshTokens callback'inde dönüşü yoktu ve bile

    return new Promise(function(resolve, reject) { 
        sdk.refreshTokens(..., function(err, new_tokens) { 
        if(error.code === 'invalid_grant') { 
         return authorize_with_api(); 
        } // ^--- this will not chain to the promise being created. 
    

    doğrudan vardı return authorize_with_api() geri arama olmadan, sonuç hala zincirlenmiş olmaz.

    bir söz gidermek için, bunun yerine kendi yapıdan döndüremez ancak açıkça verilen geri aramaları birini (çözmek/reddetmek) aramalıdır:

    return new Promise(function(resolve, reject) { 
        sdk.refreshTokens(..., function(err, new_tokens) { 
        if(error.code === 'invalid_grant') { 
         resolve(authorize_with_api()); 
        } // ^--- must call resolve here 
    

    bir söz aslında reddini kolları çözme yanı olursa olsun eğer öyleyse authorize_with_api çözer ya da reddeder, devlet zinciri buna göre ilerletir.

    Benim önerim hala erken bir dönüş if şube şartlandırma amaçlanan semantiğini korumak için return deyimi tutmaktır ama reject/resolve için Promises can only be resolved once ve diğer tüm çağrılar dikkate alınmaz çünkü kod onsuz çalışacaktır.

    return new Promise(function(resolve, reject) { 
        sdk.refreshTokens(..., function(err, new_tokens) { 
        if(error.code === 'invalid_grant') { 
         return resolve(authorize_with_api()); 
        } // ^--- should still return here for readability - clean logic purposes 
        reject('refreshTokens failed'); // this will be ignored if the above `resolve` gets called first, no matter if you have the `return` statement 
    

    Örnekler:

    function success() { 
     
        return Promise.resolve('success'); 
     
    } 
     
    
     
    function error() { 
     
        return Promise.reject('error'); 
     
    } 
     
    
     
    function alwaysPending() { 
     
        return new Promise(() => { 
     
        return success(); 
     
        }); 
     
    } 
     
    
     
    function resolves() { 
     
        return new Promise((resolve) => { 
     
        resolve(success()); 
     
        }); 
     
    } 
     
    
     
    function rejects() { 
     
        return new Promise((resolve) => { 
     
        resolve(error()); 
     
        }); 
     
    } 
     
    
     
    alwaysPending().then(console.log); // doesn't log anything 
     
    resolves().then(console.log); 
     
    rejects().catch(console.log);

    `authorize_with_api` iç tanımsız gibi görünüyor tokens`
    +1

    Mükemmel bir açıklama! _removes hat_ – montrealist

    +0

    Yardımcı olmak için sevindim :) – nem035

    +0

    'Promise' executor işlevinden' dönüş 'olmadığını, ancak içinde bir yerde eşzamanlı olmayan bir geri çağırma yaptığına dikkat edin. – Bergi

    İlgili konular