Два отказа в одном обещании - PullRequest
0 голосов
/ 21 июня 2019

Я новичок в JavaScript. Я не знаю, где я могу использовать два отказа в одном обещании; Может ли кто-нибудь сказать мне, что это плохая практика - два отказа в одном обещании? Если да, что будет необязательным решением?

Вот мой код

async handler(ctx) {
                /*
                 * sheet_to_json method converts excel file to JSON format
                */
                let { s3Url, header } = ctx.params;
                return new Promise((resolve, reject) => {
                    request({method: 'GET',  uri: s3Url,encoding: null}, async function(err, res, data) {
                        if(err || res.statusCode !== 200) reject(err);
                        try{
                            const workbook = XLSX.read(data, {type:'buffer'});
                            const sheet_name_list = workbook.SheetNames;
                            let result = await XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]], {header});
                            resolve(result);
                        }
                        catch(error){
                            reject("Invalid File Cointaint");
                        }       
                    })
                });
            }

Ответы [ 4 ]

2 голосов
/ 21 июня 2019

Вы можете иметь несколько мест, которые вы называете reject(err) внутри вашего обратного вызова обещания. Только первый исполнитель будет иметь значение. Последующие вызовы reject() игнорируются, поскольку после установки состояния Promise его нельзя изменить при последующих вызовах reject() или resolve().

.

Обычно хорошей практикой является завершение выполнения функции с помощью return или использование оператора else, когда вы отказываетесь, поскольку продолжать делать другие вещи, которые не собираются разрешать или отклонять, обычно бессмысленно, а в некоторых случаях дела вредные.

Итак, в вашем конкретном случае вы можете добавить return, например:

async handler(ctx) {
    /*
     * sheet_to_json method converts excel file to JSON format
     */
    let {s3Url,header} = ctx.params;
    return new Promise((resolve, reject) => {
        request({method: 'GET', uri: s3Url, encoding: null}, async function(err, res, data) {
            if (err || res.statusCode !== 200) return reject(err); // <==== return added here
            try {
                const workbook = XLSX.read(data, {type: 'buffer'});
                const sheet_name_list = workbook.SheetNames;
                let result = await XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]], {header});
                resolve(result);
            } catch (error) {
                reject("Invalid File Cointaint");
            }
        })
    });
}

Или вы можете добавить еще:

async handler(ctx) {
    /*
     * sheet_to_json method converts excel file to JSON format
     */
    let {s3Url, header} = ctx.params;
    return new Promise((resolve, reject) => {
        request({method: 'GET', uri: s3Url, encoding: null}, async function(err, res, data) {
            if (err || res.statusCode !== 200) {
                reject(err);
            } else {           // <======== else added here
                try {
                    const workbook = XLSX.read(data, {type: 'buffer'});
                    const sheet_name_list = workbook.SheetNames;
                    let result = await XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]], {header});
                    resolve(result);
                } catch (error) {
                    reject("Invalid File Cointaint");
                }
            }
        })
    });
}
1 голос
/ 21 июня 2019

Да, вы можете использовать любое количество reject в обещании. Просто отбраковки должны быть на другом потоке. Средства вызова одного reject за другим reject не будут работать. Как звонить один resolve за другим resolve не будет.

Также, чтобы убедиться, что другой код не запускается, рекомендуется добавить return перед reject.

Например:

const checkIfRightPermission = new Promise((res, rej) =>{
    //let's say we are doing an http request.
    request.get('/getPermission?id=someid', function(err, res, body){
        if(err){
            //the request itself couldn't be completed SO
            return rej();
        }else{
            if(sufficientPermission(body)){

            }else{
                //again
                return rej()
            }
        }
    })

});
0 голосов
/ 21 июня 2019

Нет проблем использовать множество отклонений, это полностью зависит от вашей логики, и это было сделано для использования таким образом.

Единственное, что я предлагаю вам изменить, - это блок try / catch внутри Promise, когда вы вызываете исключение, следующее обещание.catch будет обрабатывать его.

Взгляните:

https://medium.com/datafire-io/es6-promises-patterns-and-anti-patterns-bbb21a5d0918

0 голосов
/ 21 июня 2019

Вы должны попытаться сохранить каждое разрешение и отклонить его в блоке if else.

if (condition1) {
  resolve(true);
} else if (condition2) {
  reject(false);
} else {
  reject(false);
}

Например, если вы собираетесь сделать это:

if (condition1) {
  resolve(true);
}
reject(false);

Вместо этого вы должны:

if (condition1) {
  resolve(true);
  return;
}
reject(false);
...