2016-06-14 6 views
0

Я пишу модуль, который использует API Google, но я обертываю все, что является обратным вызовом, основанным на обещании. Это код проблемной областиОбещание не работает внутри обратного вызова

file1.js

var File2 = require('file2') 
var api = new File2() 
api.auth().then(auth => { 
    api.search('example').then(res => { 
    ...do some stuff... 
    }) 
}).catch(err => { 
    console.log('1') //Not being run 
    throw err 
}) 

file2.js

class File2(){ 
    auth() { 
    ...works fine and resolves... 
    } 

    search() { 
    return new Promise((resolve, reject) => { 
     googleapi.somemethod(options, (err, res) => { 
     if(err) { 
      console.log('2') // DOES run 
      reject(new Error(err)) 
     } 
     resolve(res.field) //Program crashes here because reject didn't actually reject 
     }) 
    }) 

} 

Вызов auth работает просто отлично, но призыв к search (и более конкретно googleapi.somemethod) не работает, и err определен. Я проверяю ошибку, и console.log('2') запускает, но затем console.log('1') в catch не запускается, ошибка не выбрасывается, и программа разбилась на resolve(res), потому что res не определен. Я пытался поставить ловец ошибки в качестве второго аргумента then вместо использования catch, но до сих пор не работает

api.search('example').then(res => { 
    ...do some stuff... 
}, err => { 
    console.log('2') // Still doesn't run 
    throw err 
}) 

Я бегу Узел v6.2.1

+0

Вы не должны 'return' обещание ? Также не должно быть 'else'? Похоже, что 'resolve' всегда будет вызываться независимо ... – elclanrs

+0

Я не возвращаю обещание? Я никогда не видел, чтобы кто-то делал что-то вроде > return resolve() или > return reject() А что касается остальных, возможно, вы правы. Я следую общей схеме обработки обратных вызовов, которые возвращают что-то, но да, это может не работать для обещаний. У меня всегда было это в моей голове, хотя это «разрешить» и «отвергнуть» вид действия, как возвращение, но это может быть просто дырой в моих знаниях обещаний. – Weston

+0

Проверьте мой ответ, надеюсь, что это поможет. Кроме того, неважно, что такое 'else'. – elclanrs

ответ

3

Вы должны вернуть обещание :

var File2 = require('file2') 
var api = new File2() 
api.auth().then(auth => { 
    return api.search('example').then(res => { // return the promise 
    return ... 
    }) 
}).catch(err => { 
    console.log('1') // Not being run 
    throw err 
}) 

Кроме того, если вам не нужно auth внутри search, то вы можете unnest эти обещания:

var File2 = require('file2') 
var api = new File2() 
api.auth().then(auth => { 
    return api.search('example') 
}).then(res => { 
    return ... 
}).catch(err => { 
    console.log('1') //Not being run 
    throw err 
}) 
+0

Не обращайте внимания на часть 'else'. – elclanrs

+0

После того, как вы сказали, мой 'console.log' внутри' catch' запущен, но 'throw err' не сбой программы. Любая идея, почему это было бы? – Weston

+0

'throw' не должен разрушать вашу программу внутри обещания, это по дизайну. Внутри обещания 'throw err === return Promise.reject (err)', поэтому вы будете обрабатывать ошибку в более позднем '.catch()', например '.catch (err => throw err) .catch (handleError) ' – elclanrs

3

вызов reject() не останавливает вашу программу, все коды, приведенные ниже, будут выполнены.

Пожалуйста, обновите от

if(err) { 
    console.log('2') // DOES run 
    reject(new Error(err)) 
} 
resolve(res.field) //Program crashes here because reject didn't actually reject 

в

if(err) { 
    console.log('2') // DOES run 
    reject(new Error(err)) 
} 
else { 
    resolve(res.field) //Program crashes here because reject didn't actually reject 
} 

* обновление * или вы можете сократить свой код

if(err) { 
    console.log('2') // DOES run 
    return reject(err) // no need to new Error object 
} 
resolve(res.field) //Program crashes here because reject didn't actually reject 
+0

Я тоже об этом думал, но это не так, потому что обещание может быть только в одном состоянии. Если он отвергает, то он не может решить. Я все равно буду писать его с помощью 'else', хотя это делает поток более понятным. – elclanrs

+0

или вы можете следовать второму решению, которое я обновляю выше @elclanrs –

+0

Да, это еще одна возможность сделать его понятнее, но точка по-прежнему стоит, как только вы отклоняете решение, не будет вызываться. См. Https://jsfiddle.net/g8yufxfa/ – elclanrs

Смежные вопросы