2016-11-12 10 views
-2

JS関数(NodeJS)を呼び出すコードブロックがあります。それが呼び出す関数にはPromiseチェーンが含まれています。プロミスチェーンを含む関数を呼び出します。

'use strict' 

const request = require('request') 

try { 
    const data = search('javascript') 
    console.log('query complete') 
    console.log(data) 
} catch(err) { 
    console.log(err) 
} finally { 
    console.log('all done') 
} 

function search(query) { 
    searchByString(query).then(data => { 
    console.log('query complete') 
    //console.log(JSON.stringify(data, null, 2)) 
    return data 
    }).catch(err => { 
    console.log('ERROR') 
    console.log(err) 
    throw new Error(err.message) 
    }) 
} 

function searchByString(query) { 
    return new Promise((resolve, reject) => { 
    const url = `https://www.googleapis.com/books/v1/volumes?maxResults=40&fields=items(id,volumeInfo(title))&q=${query}` 
    request.get(url, (err, res, body) => { 
     if (err) { 
     reject(Error('failed to make API call')) 
     } 
     const data = JSON.parse(body) 
     resolve(data) 
    }) 
    }) 
} 

私は、コードを実行すると、コンソールが表示query completeが検索結果に続いて:ここでは関数を呼び出すコードがあります。

次にエラーが発生します:TypeError: google.searchByString(...).then(...).error is not a functionこれは意味をなさない!このエラーはなぜ発生するのですか?

+2

Promiseライブラリを使用していない限り、 '.error()'ではなく '.catch()'が必要です。 –

+1

間違いなく '.catch'だけでなく、あなたが持っているtry/catchは、同期関数内にあり、約束のロジックが非同期であるため動作しません。 – loganfsmyth

+0

マダラの誤植を見つけてくれてありがとう。わかりやすくするために、すべてのコードを1つのスクリプトにまとめました。これで 'query complete'が得られますが、データはありません。私は、データが間違った順序で戻ってくることがわかります。 –

答えて

0

あなたはデータに戻り値を割り当てますが、約束の結果は返されません。

私がした唯一のことは、a)検索の約束を返すことと、b)解決された約束からデータを取得することです。

あなたはこのコードを見てでそれで遊ぶことができます:https://runkit.com/arthur/5827b17b8795960014335852以下

'use strict' 

const request = require('request') 

try { 
    search('javascript') 
    .then(
     data => console.log('and the data', data), 
     error => console.error('uh - oh', error) 
    ); 
    console.log('the query isn\'t done yet!'); 
} catch(err) { 
    console.error(err); 
} finally { 
    console.log('all done, or is it?') 
} 

function search(query) { 
    return searchByString(query).then(data => { 
    console.log('query complete') 
    //console.log(JSON.stringify(data, null, 2)) 
    return data 
    }).catch(err => { 
    console.log('ERROR') 
    console.log(err) 
    throw new Error(err.message) 
    }) 
} 

function searchByString(query) { 
    return new Promise((resolve, reject) => { 
    const url = `https://www.googleapis.com/books/v1/volumes?maxResults=40&fields=items(id,volumeInfo(title))&q=${query}` 
    request.get(url, (err, res, body) => { 
     if (err) { 
     reject(Error('failed to make API call')) 
     } 
     const data = JSON.parse(body) 
     resolve(data) 
    }) 
    }) 
} 

は、私は最初からそれについて移動したい方法です。私はここで最大の改善点は、ノードのURLのlibを使用していると思います。それを行うには良いことが常にあなたのために処理されます。あなたの場合には、ユーザーが "do not"のような文字列を入力すると、それは壊れるでしょう:)。

require('request'); 
// request promise is a popular, well tested lib wrapping request in a promise 
const request = require('request-promise'); 
// i like to use url handling libs, they do good things like escape string input. 
const url = require('url'); 

class Search { 
    constructor(query) { 
     this.query = query; 
    } 

    fetch() { 
     const endpoint = url.parse('https://www.googleapis.com/books/v1/volumes'); 

     const options = { 
      maxResults: 40, 
      fields: 'items(id,volumeInfo(title))', 
      q: this.query 
     } 

     endpoint.query = options; 

     const callUrl = url.format(endpoint); 
     return request.get(callUrl).then(result => JSON.parse(result)); 
    } 
} 

const search = new Search('javascript'); 
search.fetch() 
    .then(result => console.log(result)) 
    .catch(e => console.error('catch:', e)); 

、ここで作業コードです:https://runkit.com/arthur/5827d5428b24ed0014dcc537

0

Now I get query complete but no data.

request.get()操作が完了する前に、あなたがdataを記録しているためです。このブロック:

try { 
    const data = search('javascript') 
    console.log('query complete') 
    console.log(data) 
} catch(err) { 
    console.log(err) 
} finally { 
    console.log('all done') 
} 

は、それに続く同期ので、前にコードを実行します。

data = search('javascript') 

.then(function(data){ 
    console.log('query complete'); 
    console.log(data); 
    console.log('all done') 
}) 
.catch(function(err){ 
    console.log(err); 
}) 
関連する問題